problem-specifications icon indicating copy to clipboard operation
problem-specifications copied to clipboard

[Forth] "using the then-current version of those previously-defined words" issues

Open joshgoebel opened this issue 4 years ago • 5 comments

Ref:

  • https://github.com/exercism/problem-specifications/commit/c85397312197906905c295ec7d026e53159d2fd4
  • https://github.com/exercism/javascript/commit/5954afe66327540918af4cf725a881c5d8adef09

Context: Trying to solve/implement this exercise for the Wren track and getting very confused.

I wonder if we should have added this without additional instructions describing for proper behavior. I find the current tests lacking in that they do not give me enough a picture of the correct behavior. I imagine students could make them pass while still having all sorts of bugs that don't actually implement Forth.

Take the JS canonical implementation for example: it is doing "immediate evaluation"... is that correct? I'm pretty sure that simply defining a function should not execute it. Also it seems to not deal with the fact that the function in question could remove items from the stack, not just add them... it could also theoretically work with items already on the stack (passed arguments?) making evaluating it immediately impossible (you need the future stack, not the present stack). ...or what if the function references another function that's not defined yet? I see we have a try catch (perhaps to handle some of these many edge cases) but that just confirms my suspicions that we're probably handling this improperly (and likely need more far more tests).

I'm guessing that is not what Fortran is doing [immediate eval]... it feels more like closures (at a glance).. where a function definition closes on any other function definitions as they stood at the time the function is defined... so calling them later should run the actual function (with any side effects it might have) - BUT the function as it stood at the time the callee was defined, not however it might stand now. But that's just my educated guess. 🤷🏻‍♂️

  • Are we wanting this exercise to truly be so complex?
  • Have I properly understood what Fortran actually does here or is it something else?
  • Am I entirely off the track here?

CC @slaymance @Disasm

joshgoebel avatar May 06 '21 00:05 joshgoebel

I added a test case in the Rust track to address a related issue. Didn't attempt to generalize that test case into this repo because it depends on a Rust-specific implementation, but agree that the actual issue generalizes.

Anyway, my personal non-canonical answers to your questions:

simply defining a function should not execute it

100% agree

what if the function references another function that's not defined yet

UnknownWord error, just as if an immediate referenced a function that's not been defined yet. It's possible to allow for deferred name resolution, but IMO that's overkill.

a function definition closes on any other function definitions as they stood at the time the function is defined

Can't speak for Fortran, but that's the interpretation we're requiring in Rust.

Are we wanting this exercise to truly be so complex?

Yes. Forth is a capstone exercise, in that once you've implemented your own toy language, you're Definitely A Programmer. Also, it's complex by the standards of Exercism, but in comparison to day-job programming, it's pretty routine.

coriolinus avatar May 06 '21 06:05 coriolinus

UnknownWord error, just as if an immediate referenced a function that's not been defined yet.

Perhaps that's worth a test also? I don't think that's in there now... I just assumed you could declare them ahead of time as long as they were defined when you tried to use them - but I guess that was before the whole closure idea... which kind of makes that make less sense. :)

Also, it's complex by the standards of Exercism, but in comparison to day-job programming, it's pretty routine.

I was just covering the bases, not arguing for removal. :-) It's fine to have hard exercises - but if we keep I think the tests around this need to be beefed up to cover more properly show the expected behavior and actually steer the students to implement something like closures around the original function definitions instead of trying to solve it some more tacky.

And perhaps adding a blurb in the docs wouldn't hurt?

joshgoebel avatar May 06 '21 06:05 joshgoebel

UnknownWord error

Perhaps that's worth a test also?

Probably. On the one hand, specifying the behavior more thoroughly is always a good idea. On the other hand, it might feel odd to prevent lazy binding in languages like Haskell. On the gripping hand, lazy binding only really makes sense if you're not keeping track of a variety of definitions, so a test requiring UnknownWord within a definition does make sense.

perhaps adding a blurb in the docs wouldn't hurt?

Never does.

coriolinus avatar May 06 '21 07:05 coriolinus

I believe Forth language defines this behavior unambiguously. Forth uses a concept of "dictionary" with a specific word search order (newest word first) and you can't compile a new word that uses a word that is not in the dictionary.

Disasm avatar May 06 '21 14:05 Disasm

Out of the 94 exercises I've completed so far, I enjoyed Forth the most, because of two reasons:

  1. It led to me to using pest parser, and I had to come with a formal PEG for the problem.
  2. My first two implementations passed all test cases (locally) except for the alloc-attack. My final implementation passes all test cases, and is simpler than my initial attempts.

It also took the most amount of time I've spent on an exercise, but in the end, I've the satisfaction of having learned several new concepts.

asarkar avatar Jun 26 '22 11:06 asarkar