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

Going full REPL #79

Open
Jens0512 opened this issue Dec 20, 2017 · 13 comments
Open

Going full REPL #79

Jens0512 opened this issue Dec 20, 2017 · 13 comments

Comments

@Jens0512
Copy link

You know, not just re-running a file. What needs to be done?

@greyblake
Copy link
Member

greyblake commented Dec 20, 2017

There are basically two ways to do it (as far as I know):

  • Implement an interpreter. I gave it a little try, you can see here: https://github.com/greyblake/crystal-magma . It uses Crystal compiler internals to build AST and then process it dynamically. I am not an expert in writing comilers/interpreters, so it's likely I didn't do it right.

  • Another approach is actually can be possible once Crystal has incremental compilation. E.g. language Julia is also based on LLVM, but somehow they managed to create REPL, so we should ask them how exactly :)

@veelenga
Copy link
Member

veelenga commented Dec 21, 2017

Another approach is a dynamic library loading. Theoretically, it is possible to load or re-load bytecode or crystal source code using other languages (C, Lua, JS etc). I'm not an expert in this, but you can find some discussion and related projects which can help:

@Jens0512
Copy link
Author

Ok, so i've done some research. I have currently no experience with C, but it seems like C is the way to go. Suggested by @veelenga, i think dynamic library would work very well, C has a seemingly easy to implement (take a look at this) method called dlopen, which tries to load bytecode.

This is an interesting and relevant read: https://stackoverflow.com/a/384132

I am quite new (from a professionals view) i think to some aspects of programming (like interactive programming in general), and crystal, but i hope to be able to help out.

@jwoertink
Copy link
Collaborator

Hey guys, so I've been doing some tests around this to see what I can come up with. I don't know C, so going the dynamic route for me wasn't going to work out so well. I was able to come up with a concept that solves a lot of the side effects we have (i.e. calling Time.now, DB calls to delete users, etc...). This version would basically run the same way ICR does now, but with less side effects, and possibly a few additions like tab completion, history, and proper signal trapping. However, I do think there will be some other downsides to doing this as well as some other possible (not currently known) side effects. One for sure is that each command ran will be slower, though, probably not by much. Another is the requirement of some additional 3rd party libs that may require additional installs. So setup might not be as easy (at least to start).

My question to all of you (especially @greyblake and @veelenga) would be, is this something you would be cool with us re-writing ICR to do this? or would it be better for me to just make a separate repl, and we hold off until someone is able to get the dynamic stuff integrated in to this? I'm cool with either way, and obviously I know it would need to be something played with before a merge to master would even take place. Let me know thoughts so I can figure out direction.

@veelenga
Copy link
Member

veelenga commented May 3, 2018

@jwoertink
It is hard to discuss it unless there is some prototype. But here is my +1 for re-writing it if the ICR would become better. Anyway, it will be possible to move the branch to separate repo/shard.

Really cool you do some work meanwhile 😄

@jwoertink
Copy link
Collaborator

Yeah, it's just in a "test" phase currently just to see if the concept would even work. Since I know it does, I can actually start writing something. I will make a branch on my icr fork, and then link to it here so people can play with it a little. If it turns out it's not ICR worthy, then I will just push it to it's own repo 😄

@greyblake
Copy link
Member

@jwoertink I think it makes sense if you do a prototype as a separate project. And if it turns out, that it has real advantages over ICR, we ca just deprecate ICR and encourage the community to use the new tool.

@veelenga
Copy link
Member

veelenga commented May 4, 2018

@greyblake but, if this prototype is an extension to the existed ICR, wouldn't it be easier to just work on the branch in this repo?

@greyblake
Copy link
Member

@veelenga Ah, if it's a fork, then yes.

@codenoid
Copy link

how i can require "lib" in icr, (like iex with phoenix)

@veelenga
Copy link
Member

veelenga commented Oct 29, 2018

@codenoid you can require a relative file which requires all needed dependencies:

require "./my_lib/src/main.cr"

or use a wildcard:

require "./my_lib/src/*"

@yunixon
Copy link

yunixon commented Apr 26, 2020

Is it possible to keep commands history? Like in irb or iex

@jwoertink
Copy link
Collaborator

@yunixon currently built-in, I don't think so. Readline does have the ability https://github.com/crystal-lang/crystal-readline/blob/master/src/readline.cr#L9 but I don't think it's really implemented anywhere to use it. You would probably need to submit a PR to add it in.

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

No branches or pull requests

6 participants