Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3/?] Add ability to run code examples in the playground: Fetch tutorial snippet from URL by file name #542

Draft
wants to merge 33 commits into
base: main
Choose a base branch
from

Conversation

shaedrich
Copy link
Collaborator

@shaedrich shaedrich commented Apr 22, 2024

See #340

Warning

Will only work, after #544 has been merged. Works in combination with ponylang/pony-playground#205. Contains changes from #544 until db1eb11

Example: https://deploy-preview-542--pony-tutorial.netlify.app/getting-started/hello-world#the-code

Open questions

  • What to do with the non-pony files?
  • What to do with partial examples that won't run on their own?
  • no Main actor found in package 'main'

Files

Getting Started

  • hello-world-main.pony

Types

  • classes-swap-values-sugar.pony
  • classes-swap-values.pony
  • classes-wombat-constructor-invocation.pony
  • classes-wombat-constructors.pony
  • classes-wombat.pony
  • classes-zero-argument-constructors-invocation.pony
  • classes-zero-argument-constructors.pony
  • primitives-doors.pony
  • actors-behaviors.pony
  • actors-sequential.pony
  • traits-and-interfaces-marker-methods.pony
  • traits-and-interfaces-multiple-traits.pony
  • traits-and-interfaces-nested-traits.pony
  • traits-and-interfaces-nominal-and-structural-subtyping.pony
  • traits-and-interfaces-nominal-subtyping-in-pony.pony
  • traits-and-interfaces-nominal-subtyping.pony
  • traits-and-interfaces-open-world-enumerations.pony
  • traits-and-interfaces-open-world-interface.pony
  • traits-and-interfaces-open-world-typing.pony
  • traits-and-interfaces-private-methods.pony
  • traits-and-interfaces-structural-subtyping-in-pony.pony
  • traits-and-interfaces-structural-subtyping.pony
  • traits-and-interfaces-trait.pony
  • traits-and-interfaces-type-union.pony
  • structs-constructors.pony
  • structs-fields.pony
  • type-aliases-complex-types-interface.pony
  • type-aliases-complex-types-trait.pony
  • type-aliases-enumerations-apply.pony
  • type-aliases-enumerations-iteration.pony
  • type-aliases-enumerations-namespace.pony
  • type-aliases-enumerations.pony
  • type-aliases-hash-set.pony
  • type-aliases-map.pony
  • type-aliases-set-is.pony
  • type-expressions-combined.pony
  • type-expressions-intersection.pony
  • type-expressions-tuple-declaration.pony
  • type-expressions-tuple-destructuring.pony
  • type-expressions-tuple-direct-access.pony
  • type-expressions-tuple-reassignment.pony
  • type-expressions-type-alias.pony
  • type-expressions-union.pony

Expressions

  • literals-array-literals.pony
  • literals-as-expression.pony
  • literals-character-literals.pony
  • literals-floats.pony
  • literals-multi-line-string-literals.pony
  • literals-multibyte-character-literals.pony
  • literals-number-types.pony
  • literals-numeric-typing.pony
  • literals-string-literals-encoding.pony
  • literals-string-literals-instances.pony
  • literals-string-literals.pony
  • literals-triple-quoted-string-literals.pony
  • literals-type-inference-coercion.pony
  • literals-type-inference-reference-capabilities.pony
  • literals-type-inference-union.pony
  • variables-fields-constructor-assignment.pony
  • variables-fields-definition-assignment.pony
  • variables-fields-implicit-assignment.pony
  • variables-fields-let-reassignment.pony
  • variables-let-reassignment.pony
  • variables-local-variables.pony
  • variables-scope.pony
  • variables-var-vs-let.pony
  • operators-add.pony
  • operators-infix-operator.pony
  • operators-operator-aliasing.pony
  • operators-precedence-infix-and-unary-operators-with-parentheses.pony
  • operators-precedence-infix-and-unary-operators-without-parentheses.pony
  • operators-precedence-single-operator.pony
  • operators-precedence-unary-operator-with-parentheses.pony
  • operators-precedence-with-parentheses.pony
  • operators-precedence-without-parentheses.pony
  • operators-unary-operators.pony
  • arithmetic-default-integer-arithmetic.pony
  • arithmetic-explicit-numeric-conversion.pony
  • arithmetic-partial-and-check-arithmetic.pony
  • arithmetic-unsafe-conversion.pony
  • control-structures-conditionals-expression-implicit-none.pony
  • control-structures-conditionals-expression-union-type.pony
  • control-structures-conditionals-expressions.pony
  • control-structures-conditionals-if-else.pony
  • control-structures-conditionals-if-elseif-else.pony
  • control-structures-conditionals-if.pony
  • control-structures-conditionals-nested-if-else.pony
  • control-structures-iterator-methods.pony
  • control-structures-loop-expression-else.pony
  • control-structures-loop-expression-none.pony
  • control-structures-loop-expression.pony
  • control-structures-loops-for-while-comparison.pony
  • control-structures-loops-for.pony
  • control-structures-loops-repeat.pony
  • control-structures-loops-while-break-else.pony
  • control-structures-loops-while.pony
  • match-expression.pony
  • match-capabilities-only.pony
  • match-capabilities.pony
  • match-captures.pony
  • match-custom-eq-operand.pony
  • match-guards.pony
  • match-tuples-ignore-elements.pony
  • match-tuples.pony
  • match-type-and-value.pony
  • match-value-pattern-matching-vs-type-check.pony
  • match-values.pony
  • as-operator-array-literal.pony
  • as-operator-match-statement-comparison.pony
  • as-operator-match-statement-without-try.pony
  • as-operator-more-specific-interface-with-reference-capability.pony
  • as-operator-more-specific-interface.pony
  • as-operator-more-specific-type.pony
  • as-operator-unrelated-type.pony
  • methods-anonymous-methods.pony
  • methods-chaining-return-value.pony
  • methods-chaining.pony
  • methods-constructors-calling-on-expression.pony
  • methods-constructors-calling-reuse-variable-name.pony
  • methods-constructors-calling.pony
  • methods-constructors.pony
  • methods-default-arguments.pony
  • methods-functions-calling-implicit-this.pony
  • methods-functions-calling.pony
  • methods-functions.pony
  • methods-named-and-positional-arguments-combined.pony
  • methods-named-arguments.pony
  • errors-dispose-multiple.pony
  • errors-dispose.pony
  • errors-partial-functions.pony
  • errors-try-else.pony
  • errors-try-then.pony
  • errors-try-without-else.pony
  • errors-with-blocks.pony
  • equality-equatable-default-implementation.pony
  • equality-identity-equality.pony
  • equality-primitives.pony
  • equality-structural-equality.pony
  • sugar-apply-explicit.pony
  • sugar-apply-implicit.pony
  • sugar-apply-with-arguments-explicit.pony
  • sugar-apply-with-arguments-implicit.pony
  • sugar-create-apply-combined-explicit.pony
  • sugar-create-apply-combined-implicit.pony
  • sugar-create-explicit.pony
  • sugar-create-implicit.pony
  • sugar-create-with-arguments-explicit.pony
  • sugar-create-with-arguments-implicit.pony
  • sugar-update-additional-parameters.pony
  • sugar-update-explicit.pony
  • sugar-update-implicit.pony
  • object-literals-actor-literal.pony
  • object-literals-closing-over-values.pony
  • object-literals-fields-assignment.pony
  • object-literals-lambda-as-explicit-object-literal.pony
  • object-literals-lambda-capture-and-rename-values.pony
  • object-literals-lambda-capture-values.pony
  • object-literals-lambda-reference-capabilities-2.pony
  • object-literals-lambda-reference-capabilities.pony
  • object-literals-lambda-with-reference-capability-as-explicit-object-literal.pony
  • object-literals-lambda-with-reference-capability.pony
  • object-literals-lambda.pony
  • object-literals-object-literal-with-interface.pony
  • object-literals-object-literal.pony
  • object-literals-reference-capability.pony
  • partial-application-callback-function-with-all-arguments-bound.pony
  • partial-application-callback-function-with-no-arguments-bound.pony
  • partial-application-callback-function-with-out-of-order-arguments.pony
  • partial-application-callback-function-with-some-arguments-bound.pony
  • partial-application-partially-applying-a-partial-application.pony

Reference capabilities

  • reference-capabilities-constructors-for-different-capabilities.pony
  • reference-capabilities-default-vs-explicit.pony
  • reference-capabilities-string-capabilities.pony
  • reference-capabilities-string-default.pony
  • reference-capability-specificy-a-capability-other-than-the-default.pony
  • consume-and-destructive-read-consuming-a-variable-and-change-its-reference-capability.pony
  • consume-and-destructive-read-consuming-a-variable.pony
  • consume-and-destructive-read-moving-a-value.pony
  • recovering-capabilities-format-int.pony
  • recovering-capabilities-ref-to-iso.pony
  • recovering-capabilities-string-append.pony
  • recovering-capabilities-with-explicit-reference-capability.pony
  • aliasing-alias-types.pony
  • aliasing-ephemeral-types.pony
  • aliasing-iso-to-tag.pony
  • aliasing-multiple-references-to-an-iso-object.pony
  • aliasing-trn-to-box.pony
  • arrow-types-box.pony
  • arrow-types-this.pony
  • arrow-types-type-parameter.pony

Object capabilities

  • derived-authority-authority-hierarchies.pony
  • derived-authority-delegating-and-restricting-authority.pony
  • derived-authority-restrict-then-delegate-your-authority.pony

Generics

  • generics-and-reference-capabilities-accept-any-reference-capability.pony
  • generics-and-reference-capabilities-capability-generic-class.pony
  • generics-and-reference-capabilities-default-capability-and-constraint.pony
  • generics-and-reference-capabilities-explicit-constraint-and-default-capability.pony
  • generics-and-reference-capabilities-foo-iso-consume-iso-constructor-parameter.pony
  • generics-and-reference-capabilities-foo-iso-consume-iso-function-parameter.pony
  • generics-and-reference-capabilities-foo-iso.pony
  • generics-and-reference-capabilities-foo-ref-and-this-ref.pony
  • generics-and-reference-capabilities-foo-ref.pony
  • generic-constraints-foo-any-read.pony
  • generics-foo-non-generic.pony
  • generics-foo-string.pony
  • generics-foo-with-any-val.pony
  • generics-generic-class-initialization.pony
  • generics-generic-methods.pony
  • generics-type-parameter-defaults-definition.pony
  • generics-type-parameter-defaults-initialization.pony

Packages

  • use-statement-collections.pony
  • use-statement-scheme-indicators-optional-package-scheme-specifier.pony
  • use-statement-scheme-indicators-required-package-scheme-specifier.pony
  • use-statement-time-now.pony
  • use-statement-time.pony
  • use-statement-use-names-conflict.pony
  • use-statement-use-names-resolution-alternative.pony
  • use-statement-use-names-resolution.pony

Testing

  • ponycheck-ponytest-for-all.pony
  • ponycheck-ponytest.pony
  • ponycheck-usage-quickcheck.pony
  • ponycheck-usage.pony
  • ponytest-aggregation.pony
  • ponytest-example.pony

C-FFI

  • c-ffi-callbacks-bare-functions-pass-to-c-api.pony
  • c-ffi-callbacks-bare-functions.pony
  • c-ffi-callbacks-bare-lambda-callback.pony
  • c-ffi-callbacks-bare-lambda-struct.pony
  • c-ffi-callbacks-sqlite3-callback-2.pony
  • c-ffi-callbacks-sqlite3-callback.pony
  • c-abi-jump-consistent-hashing.pony
  • c-abi-pony-use-native-jump-consistent-hashing-c-implementation.pony
  • calling-c-access-list-entry-with-explicit-return-type.pony
  • calling-c-access-list-entry-without-return-type.pony
  • calling-c-addressof.pony
  • calling-c-default-method-in-primitive.pony
  • calling-c-default-method-in-trait.pony
  • calling-c-different-types-of-lists.pony
  • calling-c-ffi-functions-raising-errors.pony
  • calling-c-file-path.pony
  • calling-c-from-c-struct.pony
  • calling-c-generic-list.pony
  • calling-c-ioctl-struct.pony
  • calling-c-memcpy.pony
  • calling-c-pointer-to-opaque-c-type.pony
  • calling-c-type-signature-compatibility.pony
  • calling-c-variadic-c-functions.pony
  • calling-c-writev-struct.pony
  • calling-c-writev-tuple.pony
  • linking-c-use-lib-foo.pony
  • linking-c-use-with-condition.pony

Gotchas

  • divide-by-zero-floats.pony
  • divide-by-zero-partial.pony
  • divide-by-zero-unsafe.pony
  • divide-by-zero.pony
  • garbage-collection.pony
  • scheduling.pony
  • function-call-side-effects.pony
  • recursion.pony

Appendices

  • appendices-annotations-empty-with-nosupertype-annotation.pony
  • appendices-annotations-empty-without-nosupertype-annotation.pony
  • appendices-annotations-likely-and-unlikely-annotations.pony
  • appendices-annotations-nodoc-annotation.pony
  • appendices-annotations-packed-annotation.pony
  • appendices-annotations-syntax.pony
  • appendices-examples-access-command-line-arguments.pony
  • appendices-examples-create-arrays-with-values.pony
  • appendices-examples-empty-class-functions.pony
  • appendices-examples-enumeration-with-values-with-namespace.pony
  • appendices-examples-enumeration-with-values.pony
  • appendices-examples-iterable-enumerations.pony
  • appendices-examples-modify-a-lexically-captured-variable-in-a-closure.pony
  • appendices-examples-operator-overloading.pony
  • appendices-examples-pass-array-of-values-to-ffi.pony
  • appendices-examples-test-helper.pony
  • appendices-examples-use-cli-package-to-parse-command-line-arguments.pony
  • appendices-examples-write-tests.pony
  • appendices-platform-dependent-code.pony
  • appendices-serialization-compare-original-object-with-deserialized-object.pony
  • appendices-serialization-custom-serialization.pony
  • appendices-whitespace-comments.pony
  • appendices-whitespace-do-a-then-do-a-unary-negation-of-b.pony
  • appendices-whitespace-docstrings.pony
  • appendices-whitespace-subtract-b-from-a.pony
  • error-messages-left-side-is-immutable.pony
  • error-messages-left-side-must-be-something-that-can-be-assigned-to.pony
  • error-messages-receiver-type-is-not-a-subtype-of-target-type.pony

shaedrich and others added 28 commits April 21, 2024 05:35
to mark array entry as object rather than a string
@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Apr 22, 2024
MD031 - Fenced code blocks should be surrounded by blank lines
@jemc
Copy link
Member

jemc commented May 14, 2024

What to do with the non-pony files?

As discussed in the previous PR, please leave those ones out of the code-samples subdirectory - leave out anything we don't plan to test by compiling.

What to do with partial examples that won't run on their own?

We suggest using the ability to show a partial snippet of a code sample for a given set of lines, so that we can show only the partial example, but the outer code (hidden) would make the file in the code-samples directory compilable.

no Main actor found in package 'main'

The same idea applies - we can put actor Main in one of the hidden lines of the code sample file, outside the partial snippet that is shown.

@shaedrich
Copy link
Collaborator Author

shaedrich commented May 15, 2024

What to do with partial examples that won't run on their own?

We suggest using the ability to show a partial snippet of a code sample for a given set of lines, so that we can show only the partial example, but the outer code (hidden) would make the file in the code-samples directory compilable.

no Main actor found in package 'main'

The same idea applies - we can put actor Main in one of the hidden lines of the code sample file, outside the partial snippet that is shown.

Would you like this to be addressed here or in #544?

The problem with wrapping every code sample in an actor and calling it is, that it creates a whole lot of boilerplate code. This could possibly be done by the playground instead in ponylang/pony-playground#205

@shaedrich
Copy link
Collaborator Author

shaedrich commented May 16, 2024

Okay, I tested an implementation into the playground, and while it is possible to implement, it will a) not work in all cases and b) not be versatile enough to be beneficial. However, I don't think, this should be done in #544, since this will be an additional huge amount of work, as every snippet needs to be tested and additional hidden code parts must be determined, separately. Maybe, this could even be done in another PR to keep track of the changes and their progress. Furthermore, technically, some pending draft PRs could be done in the meantime already, then.

@SeanTAllen
Copy link
Member

I don't think wrapping should be done by the playground. Having in sample but only displaying some in tutorial seems appropriate. I'm ok with that being a separate PR.

@jemc thoughts?

@shaedrich shaedrich changed the title [2/?] Add ability to run code examples in the playground: Fetch tutorial snippet from URL by file name [3/?] Add ability to run code examples in the playground: Fetch tutorial snippet from URL by file name May 20, 2024
@shaedrich
Copy link
Collaborator Author

@SeanTAllen I added said PR just in case and listed my progress there alongside some questions: #545

Copy link

netlify bot commented May 21, 2024

👷 Deploy request for pony-tutorial pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 469dabf

@jemc
Copy link
Member

jemc commented Jun 4, 2024

additional huge amount of work, as every snippet needs to be tested and additional hidden code parts must be determined, separately

I don't think the snippets need to be tested in terms of verifying their runtime behavior - that would indeed be a huge amount of work.

We just need to validate that they compile successfully.

This was discussed briefly in the sync call.

@SeanTAllen SeanTAllen removed the discuss during sync Should be discussed during an upcoming sync label Jun 4, 2024
@shaedrich
Copy link
Collaborator Author

I don't think the snippets need to be tested in terms of verifying their runtime behavior - that would indeed be a huge amount of work.

We just need to validate that they compile successfully.

Well, if they unexpectedly throw an error in the playground, they are no use. But you'll see that reflected in the PR description and comments in #545

@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Jun 4, 2024
@jemc
Copy link
Member

jemc commented Jun 4, 2024

unexpectedly throw an error

They won't throw a compilation error, right? That's what we want to test for, so that should indeed be covered by this work.

If you mean a runtime error, well, in idiomatic Pony (and these samples are definitely supposed to be idiomatic Pony), errors are handled so tightly that nothing really "unexpectedly throws an error" at runtime. What you have at most are flaws in program logic,.

It's not impossible that some breaking change in the compiler would cause a logic bug to appear in a code sample, but the probability should be vanishingly unlikely - that's the worst possible kind of breaking change we could make in the compiler or standard libraries, because it would also have that "subtle logic bug" effect on user-land code. We have an extreme aversion to introducing changes that would cause such "subtle logic bugs" so we take every effort we can to ensure that breaking changes in Pony will "fail loudly" at compile time.

Put all this together with the fact that making all these code samples behavior-testable would be a massive amount of work (likely an order of magnitude or more greater than what you've already done), and I just don't believe it's worth the effort, either for you or for people we're asking to write new tutorial content in the future.

In general, testing the runtime behavior of Pony programs for breaking changes should be done using our "runner tests" in the ponyc repo - it's not really a concern of the tutorial repo.

@shaedrich
Copy link
Collaborator Author

My choice of words might not have been ideal in reflecting technical details, however, what people care at the end of the day is:

  • Tutorial talks about something
  • They encounter a code snippet
  • They click on the button below code snippet
  • Playground: 💥

That's what they will see in some cases while what they expected will be "Hello world". They will feel lied to or at least that nobody bothers if the examples work.

Tutorial users won't necessarily be experts on Pony and might not be able to fix logic errors other contributors committed and nobody checked.

would be a massive amount of work

I've already essentially documented all the expectations in #545 while doing that PR so it's more or less copy and paste. No real additional work to do here.

@jemc
Copy link
Member

jemc commented Jun 4, 2024

what people care at the end of the day is:

I agree 👍

My position is that breaking changes from upstream that cause subtle logic flaws are vanishingly unlikely, so I don't expect that to be a problem in practice. So I think that skipping the work of running the examples (i.e. only compiling them) will still accomplish the goal that "people care at the end of the day", but without the extra burden of needing to create/curate runtime output expectations for every tutorial sample snippet. I think we should only focus on ensuring that the tutorial snippets continue to compile.

Comment on lines +53 to +59
main.pony:5:8: right side must be a subtype of left side
_c = c
^
Info:
main.pony:4:17: String iso! is not a subtype of String iso: iso! is not a subtype of iso
new create(c: String iso) =>
^
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks unrelated to the change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kinda. This was because the PR was created alongside previous PRs and when we reverted non-pony examples and cherry-picked them, not everything looked exactly pretty in the commit history 😅

@@ -21,6 +21,8 @@ In your file, put the following code:
--8<-- "hello-world-main.pony"
```

[:fontawesome-solid-play: Run in playground](https://playground.ponylang.io/?snippet=hello-world-main.pony){ .md-button .md-button--primary target="_blank" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way we could automatically render this button for every .pony snippet instead of needing to paste this button code ourselves all over the markdown, and maintain that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and no. Not with the current setup. But that's why I'm experimenting with #555.

@SeanTAllen SeanTAllen removed the discuss during sync Should be discussed during an upcoming sync label Jun 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants