Replies: 12 comments
-
For a language to be consistent it has to have consistent semantics not based on context. As far as I see from the PR comments. You are not designing a functional language but a script evaluator that is changing the values of some global variables ad-hoc. So I will suggest some functional semantics to understand what you want. Case of returning nothing Expressions that are not assigned
The right semantic for this
This is possible. Because even in functional languages we need to create side effects sometimes. But that reads as "I want to create a side-effect". Is it really what you want? Side effects that are changing things that are not visible in the script! There is something that smells there. Think twice. Think quadruple... Maybe there is another way that can do it explicitly. An example of getting rid of no assignment statements and making them explicit
Returning multiple results
or
A note about semantic rules. A typical semantic rule example And with explicit semantic rules, we can explain the user how the language works... Instead of saying this is what you write but this what we do behind the scenes. An actual good case of returning nothing in a functional language However, if you go this way no body should map the function internals to typescript or try to access them!!! Because they contain wild unreduced code. There is always a solution without breaking purity. Let's see what you need. |
Beta Was this translation helpful? Give feedback.
-
Just some context about why I think this is the most important feature after #226. I'm personally very excited about reducer, but I'm also excited that we might be able to get back to Squiggle Notebooks again. The reason why I am talking to you about returning bindings from calls is because it would be great if something like below (where donation_size is referenced in a succeeding cell) could be done with reducer. I am extremely stupid, and I usually think of the dumbest and simplest way to do things, so in my mind the easiest way would be return the bindings at the end of the execution call, and that if that was done, I could get reducer style squiggle notebooks? |
Beta Was this translation helpful? Give feedback.
-
I mean like, internally, I could imagine that every code block returns something like: x = 2
y = 3
x + y
x - y Actually ends up returning:
With a way to pass the bindings back in as context would be fine. I don't think that breaks purity? If that would be an issue, could you tell me what type of semantics the above notebook ends up having? Also now you are enabling such stupid scripts with nameless array of exports. And you are burdening the runtime memory usage. Because people can just write long scripts although they wont use the unassigned values there. Memory nightmare. Hmm one moment. There is no need to give users an array constructor. They can always write a block. Shouldn't all languages be doing that? :) |
Beta Was this translation helpful? Give feedback.
-
I think just a record of all variables is just what you need. (PineScript does it).
And just name x+y, x-y so that they are there alo. Otherwise this practice leads to many bugs... Nameless things leads you to make indexing mistakes. Returning an array of exported values is asking for trouble. |
Beta Was this translation helpful? Give feedback.
-
The variable record and actually returning bindings have a huge difference. Because then every expression has to return a tuple of bindings. x = 1 + 2 becomes (x, bindingsNow) = (bindings, 1)->{ prevBindings | (prevBindings, 2)->add
Because in the future people will be able to write
Instead of getting a record of variables then the code above becomes
To be able to return actual bindings blocks we end up making every expression returning bindings. Therefore a block is a scope that returns one thing. And returning a record of all variables fall into that category without streching. This way, there are no exceptional cases in the language and I can just write
GET A RECORD OF VARIABLES. That said, now I am thinking about removing the array constructor {a: 1, b: 2} all together from the next parser. There is no need. Every block can return a record anyway... AND Anyway I will return a record of globals and start calling it bindings to apeace you :)
And the actual bindings will have extra variable you've never declared. Because of optimization in the future. Example. {y = x+1+2; z=x+1+3}. Optimizer can turn this into {tmp1 = x+1; y=tmp1+2; z = tmp1+3}. And the order of execution of statements will change also for the sake of optimization. You will get your anonymous exports in a random order! A language where changing the order of statements changes the results is not a functional language anymore! It is as good as trashing it and returning to genuine javascript. From now on I am calling a record of global variables, bindings! |
Beta Was this translation helpful? Give feedback.
-
Now I will propose a new perspective to test what you want. I keep asking why you need a language interpreter other than javascript? |
Beta Was this translation helpful? Give feedback.
-
OPTIMIZATION ASPECT
Change the execution order of statements An exported array of expressions is not reliable So relying on exports and bindings says "don't optimize". We should look for something more explicit.
This is even more proper
Maybe import/export are not the right keywords. Think
Also imagine I add type checking to this language. Blocks that does not return or export is a type-checking headache. |
Beta Was this translation helpful? Give feedback.
-
Implicit import/export will be available. While discussing with Sam, I found a way to solve both within the design of the language. |
Beta Was this translation helpful? Give feedback.
-
Great to hear! Looking forward to the future steps for that. |
Beta Was this translation helpful? Give feedback.
-
@Hazelfire , @OAGr A future optimization is cancelled. Also when a variable was not used it would not be executed. Cancelled out... |
Beta Was this translation helpful? Give feedback.
-
This would be nice to eventually add, but would need something like this. |
Beta Was this translation helpful? Give feedback.
-
Understood. I think I'm fine accepting some trade-offs of efficiency, for increased debuggability/interpretability. |
Beta Was this translation helpful? Give feedback.
-
On this PR, @Hazelfire mentioned:
"I think I'd like to see a couple of critical features that might require you to give up on the concept of lisp like purity within the reducer"
On the other hand, this would break some purity. Arguably, these functions could just return records with all the intended bindings, like so:
{ x=1; y=2; %{x: 1, y: 2}}
or
{ ... {firstDistribution: firstDistribution, secondDistribution: secondDistribution} }
(Examples from @umuro)
Beta Was this translation helpful? Give feedback.
All reactions