Closed dubek closed 8 years ago
This is cool... and looks good so far. A few thoughts:
usec-diff
seems generally useful in combination with sys.gettimeofday?
, maybe it should be in a posixprelude.bn
file that gets loaded by boneposix.c
, what do you think?
Since sys.gettimeofday?
may return false on failure, we should check for that. Probably posixprelude.bn
should contain a convenience subroutine like:
(defsub (gettimeofday)
"..."
(aif (sys.gettimeofday?)
it
(err "...")))
How about renaming usec-diff
to timeofday-diff
? This suggests the relation to sys.gettimeofday?
.
Maybe rename measure
to measure-time
?
By the way, what about copyright notices and licensing info in the files?
All suggestions sounds good, I'll try them (not sure I'll get to it today).
As for the copyright notices, I'm not sure what I should do. How is it different than adding some lines to an existing file? I don't mind handing you the copyright to the code (it's gonna stay in your project...). Let me know if I should copy the template from the other files.
BTW - I have a hidden agenda with all these small contributions - I want to try to implement Mal ( https://github.com/kanaka/mal ) in bone-lisp. I'm still not sure how can I implement something like env_set (mutable key-value map) using bone-lisp (and there's the memory mgmt thing to wrap my head around, but that's the whole idea of this exercise :-).
Copyright: The correct thing would probably be to add your name to all files that you have changed, and put only your name in files that you created. Copyright assignment is not possible in all countries. But if you prefer to stay anonymous, you can also just copy the header with my name from other files. The most important thing is that there is a license statement.
Mal: That's going to be interesting. If you use a tree to store an environment, you don't have to copy too much data when creating a new version of the environment. You could try to use reg-loop
as a copying garbage collector (but currently, copying does not recognize shared subtrees).
The easy solution would be to add mutable hash tables that need to be deleted manually. There is a hash table implementation already, so it's trivial to make it available to Bone code. But then you've got nothing to wrap your head around anymore. ;)
Feel free to always discuss your ideas about implementing Mal here (you could open an issue for such a discussion, for example).
I just realized: Since bone_init()
does not load prelude.bn
, bone_posix_init()
also should not load posixprelude.bn
. That should be done in main()
to be consistent. I got that wrong above.
We can have (use posixprelude)
at the end of prelude.bn
, or add a bone_load("posixprelude");
in main.c
. Identical effect, I believe. IMO clearer in main.c
.
Re: mutable hash table - I thought all bone data types are immutable... So I assumed you wouldn't want to add it.
I don't mind performance, so the env map can be alist and set(k,v) can return a new alist, and then use reg-loop to replace the "current-env". Then comes the atom data type (similar to Clojure atom) which is mutable... The Erlang implementation of Mal resorts to holding a separate erlang process for each mutable object (mal env or mal atom).
Another try at gettimeofday
and std/bench
(force-pushed to same branch).
Re posixprelude: This should not be in prelude.bn
, because the POSIX module is supposed to be optional. main()
is a good place because that's where we decide whether we activate the POSIX bindings. I.e. a program that wants to include Bone Lisp as a scripting language would not include main.c
anyway and should be able to use prelude.bn
unaltered.
Re immutability: Well, I am not dogmatic about it at all (in fact, there is already _var!
which changes a global binding, though it's intended for internal use only), but there is a reason for chosing immutability: It's the simplest way to ensure that there won't be any dangling pointers. For example:
(with x 0
(in-reg (set! x (list 0)))
x
This would return a dangling pointer. For the same reason, Bone does not have reg-new
/reg-destroy!
but restricts the use of regions to in-reg
and reg-loop
.
However, there is nothing preventing us from providing an unsafe
module. (But note that the current VM implementation does not allow the implementation of set!
because closures have their own copys of bindings; this avoids a bit of indirection when accessing free variables).
I did not work on this so far because I want to see how far I can get without it, and don't want to be tempted to use these features all the time. :) But I expect that eventually they will probably be added anyway.
Thanks for the sys.errno fix.
Re: immutability: According to the classic Lisp process, eventually you'll have to write a Bone Lisp evaluator in Bone Lisp :-) The question is whether you have the tools to do it. I'm also interested in the "how far can you go without mutability".
Commit 1
Microsecond-timing available via
sys.gettimeofday?
(addedtests/posix.bn
too):Commit 2
Add
std/bench
module to allow measuring elapsed time of code:As for the second commit, I'm not sure the names I chose (
usec-diff
,measure
,say-time
) are the best fit. Suggestions for changes are welcome.