koka-lang / koka

Koka language compiler and interpreter
http://koka-lang.org
Other
3.27k stars 163 forks source link

Read console input? #216

Open tjpalmer opened 2 years ago

tjpalmer commented 2 years ago

How do I read from the console? I see some references like here and an implementation (just for cs?) here, but I haven't been able to find any way to make it work. (I haven't gotten the cs target to work, either, for that matter.)

Is console input supported at all right now?

tjpalmer commented 2 years ago

I found the --include=... option and tried adding the v1 dir, but I still get this error:

compile: /home/tjpalmer/projects/koka/lib/v1/std/os/readline.kk
/home/tjpalmer/projects/koka/lib/v1/std/os/readline.kk(17,10): error: invalid syntax
 inline, noinline, rec, co, open, extend, value, reference, scoped or linear
tjpalmer commented 2 years ago

More detail:

$ stack exec koka -- --include=/home/tjpalmer/projects/koka/lib/v1 --target=jsnode -e /home/tjpalmer/contextfree/procfun/guess.kk
compile: /home/tjpalmer/contextfree/procfun/guess.kk
loading: std/core
loading: std/core/types
loading: std/core/hnd
loading: std/num/random
loading: std/num/int32
loading: std/num/double
loading: std/text/parse
compile: /home/tjpalmer/projects/koka/lib/v1/std/os/readline.kk
/home/tjpalmer/projects/koka/lib/v1/std/os/readline.kk(17,10): error: invalid syntax
 inline, noinline, rec, co, open, extend, value, reference, scoped or linear

And my source file, which I'm trying to work on for a YouTube video about pure and impure functions and effects and such.

daanx commented 2 years ago

Hi @tjpalmer , yikes, that is embarrassing -- all these fancy effects but no readline :-) The underlying reason is that readline is actually not so easy and the plan is to integrate libuv and provide an async API using algebraic effect handlers (with general cancelation and timeouts). I hope to get an initial integration done in the coming month(s). This already used to work which is what you see in the v1 version where NodeJS was used to provide the asynchronous primitives -- it is partly described in this tech report: https://www.microsoft.com/en-us/research/wp-content/uploads/2017/05/asynceffects-msr-tr-2017-21.pdf

Anyways, for now I just pushed an update to the feature/borrow branch that has a std/os/readline/readline function so we can at least construct examples with that -- this one is blocking though. (The plan is to put the async versions under their own directory, like std/async/readline etc. ). If you can build Koka this will work now, but otherwise you will have to wait until early next week when I push a fresh release of Koka v2.3.4.

daanx commented 2 years ago

Ah, the readline function is only for the C backend for now... The C# backend is behind and currently not working (although it could be made to work with not much effort). -- however, given the limited resources, we focus currently on the C / WASM backend, and the JS backend.

daanx commented 2 years ago

Nice source -- I see you use srandom-int32-range which provides strong random numbers. You may want to use random-int() though which has the random effect. You than handle that using either pseudo-random(seed,action) or strong-random(action) to use either pseudo random or strong random numbers. Unfortunately though, we don't yet provide random-int-range though...

tjpalmer commented 2 years ago

Thanks for all the info! I meanwhile hacked my own sync readline for jsnode. I'd prefer sync readline for c for my current case, though.

tjpalmer commented 2 years ago

For the implementation on your branch, I'm getting this error:

uncaught exception: unable to read from stdin: No such file or directory
daanx commented 2 years ago

I think it is fixed now -- should have tested on Linux :-)

(ps, if you are ok can you show me how to do a synchronous readline on NodeJS, I will include that as well)

tjpalmer commented 2 years ago

That did the trick. Thanks much! And this is going into the official release next week, too?

tjpalmer commented 2 years ago

And on random numbers, I used strong random because that's fun. Is there an important reason to use pseudorandom? And what's the semantic difference between random and ndet? Is random supposed to mean based on some random state but otherwise deterministic?

daanx commented 2 years ago

Great, yes, it'll go in the next release. The random and ndet effects are interesting: ndet is builtin for true non-determinism like, say, the result of listening on a network connection or getting strong random numbers from the OS. On the other hand random is a regular effect which exposes the random-int operation: we can handle that effect ourselves by either using a handler for, say, pseudo random numbers (either with a fixed seed which is great for repeatable debugging, or by using a strong random seed and then using a faster pseudo random generator from there on), or we can handle it using strong random numbers -- the latter handles the random effect, but in turn induces the ndet effect:

fun strong-random(action : () -> <random,ndet|e> a) : <ndet|e> a 
  with fun random-int32(){  srandom-int32() }
  action()

In the extreme, we may just return the same number all the time:

fun fixed-random(action : () -> <random|e> a) : e a 
  with fun random-int32(){  0.int32 }
  action()

this has the same signature as pseudo-random and just removes the random effect turning it into a pure computation (if e happens to be pure/total).

so, random gives more control as you can later determine in main how you are going to handle it.

tjpalmer commented 2 years ago

Thanks much for the info! Also, here's my quick hack node readline. You can imagine ways to improve that. I also don't know if fd 0 works in Windows. There's also an npm package out there, but it's easy more code. I didn't look closely at it, although I tried using it directly with Koka, but it didn't seem to import.

Completely tangent, I tried wasm output because I'm looking for languages usable for the WASM-4 fantasy console. But the Koka wasm file I got was way bigger than the 64k limit. If you're interested in more details, I can write a separate issue on basic requirements for supporting wasm-4.

daanx commented 2 years ago

Thanks for the node readline trick -- that should work I think. I see that the WASM-4 has 64 KiB memory ... currently Koka is targeting 32- and 64-bit systems with more memory so it would not be suitable.

(However, there is no fundamental reason why it could not work as Koka only relies on (some of) libc -- but you should use at least --fstdalloc to not use mimalloc (which is unsuitable for such small systems) and I guess we would really need to split up the std/core library for a minimal version without doubles etc. This may be a lot of work..)

tjpalmer commented 2 years ago

Thanks much for the reply on that!

daanx commented 2 years ago

std/os/readline should be in the latest release now (v2.3.6)

tjpalmer commented 2 years ago

I've tested just the C back end for the new release, but it seems to be working. Thanks much!