This way, the best we can do is to bring Arc's performance nearer MzScheme's performance. If we really want Arc to be fast we should implement a real Arc -> binary code compiler. Even without optimizations the code would result fast enough. The problem is that such a task requires a lot of skills and a lot of time.
Anyway, maybe the right way to do so is by destructuring a Scheme implementation ? Starting from a given implementation, you write your compiler from scratch, but use the facilities of the chosen implementation for the reader and the GC. Then, once it's working, you gradually remove the scaffolding by implementing these things by hand...
I tried that. Not very easy as Ikarus' hash-tables don't work like mzscheme's (there is no "equal" hash-tables). You would have to rewrite the reader too. And I'm not sure we would get all the stuff with sockets and networking. It doesn't have an FFI yet, either.
Well, actually, I'm not sure if implementing a still-designed language in the beta-release of a compiler is a long-term solution... :) Maybe in a few months / years this could be done ? But as for now, I think porting it to CL would be easier.
If you look in the long term run the best (and most difficult) solution would be to write an Arc compiler that translates Arc code directly in machine code.
I also suggest that. In fact, looking at Chicken's implementation - stack == heap - is rather inspiring, because it shows exactly how a garbage-collected memory manager should be done: just decrement a pointer, in this case the stack pointer. Brilliant IMO. Wish I'd thought of that.
As I have remarked before, treeparse was influenced by Haskell's parsec. One of the features of parsec is the optional infusion of more meaningful error messages into grammars. One could easily imagine adding this functionality to treeparse.
Interesting. I suppose this means that (at least for the cps version of treeparse) a fail must also "return" an error value (potentially just a "Expected lit %c, not found"). Of course 'alt parsers would ignore the error message, and generate its own when all alternatives fail ("No alternatives found"). Hmm. I think if the fail continuation returned an error message, we could create a filt-style parser (for the cps case):
For the monadic version, our old nil-as-fail code would have to be changed I suspect; basically instead of the old type Return = Return parsed remaining actions | nil, we'll need type Return = Return parsed remainig actions | Failed message .
To discover the line of the error the interpreter should provide a way to associate every form or symbol passed to the macro with its line number. As an example there could be a function such as (line-num form-with-an-error) to get the line number.
My "attachments" idea was conceived with this potential use too - jus attach the line number to the object, which acts just like the original object (i.e. matches with 'is, etc.).
Within the file gtk.arc there is a sample 'hello world' app. If I find some time I'ill work on a sligthly more complicated example :). At the moment I'm more concentrated on importing as much useful functions as possible.
Edit: By any chance, is there any particular package/library/config needed for gtk+ bindings?
I got the following error:
Error: "ffi-lib: couldn't open \"libgtk-x11-2.0.so\" (libgtk-x11-2.0.so: cannot open shared object file: No such file or directory)"
Inspecting my /usr/lib reveals that I have libgtk-x11-2.0.so.0 , which is a link to libgtk-x11-2.0.so.0.1200.0 . I tried linking libgtk-x11-2.0.so to that library, but even though the hello world window exists and opens, when I close it or click it, mzscheme crashes ^^.
Hmm, how big is the change in the naming anyway? I mean, it could conceivably just be in the same state as 'cdar is in the language today - it's not there yet but there's a name reserved for it already.
The naming strictly follows gtk+ naming, with '_' replaced by '-'. As an example gtk_widget_show_all becomes gtk-widget-show-all. gtk+ names are so long that I think they will never collide with other names.
Hmm. In such a case I doubt that lazy importing would hurt badly, since the names already unlikely to collide (not never - someone might make a Great Transformer Kollider library involving midgets, except they misspelled it as widgets (dyslexia's a bummer for programming you know, it's hard to see the difference between i and ! sometimes)); think of it as "cdar", which isn't in arc yet but which pg is too lazy to add "just for completeness".
I've tried it on linux with gtk 2.6 (quite old) with libgtk-x11-2.0.so as a link to libgtk-x11-2.0.so.0.600.4.
I don't know why it crashes, on my computer it works correctly.
What's the error message exactly?
it just core dumps without a message IIRC. Incidentally I actually had to modify the ffi.arc to add "-fPIC" to the gcc command, I have no idea why (Position Independent Code, yes, but what for? for the .so?) but ld complains if I don't and suggests that to me.
As an aside, I'm using an intel core duo, on a 64-bit SMP kernel. I don't know what those terms mean (core duo? like what, apple cores?), I'm a software hacker, not a hardware one. ^^ Oops, scratch that, okay my boss thinks I'm a hardware hacker but I hack FPGA's, not microprocessors and kernels ^^.
Also, I'm on an Ubuntu 7.10 box, with libgtk2.0-0 installed, which provides /usr/lib/libgtk-x11-2.0.so.0.1200.0 and is described as "This package contains the shared libraries.". However Ubuntu also has another package, libgtk2.0-dev (not installed on my computer), which is described as "This package contains the header files and static libraries which is needed for developing the GTK+ applications." Should I be using the -dev version?
tried again with the latest version. Running plain, once I load gtk.arc:
/usr/bin/ld: /tmp/ccwElZvz.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/tmp/ccwElZvz.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
Modifying ffi.arc to add -fPIC to gcc call:
arc> (load "gtk.arc")
*** redefining cdef
*** redefining w/ffi
*** redefining w/inline
*** redefining w/del
gs1789.c: In function ‘inc_pt’:
gs1789.c:3: warning: cast from pointer to integer of different size
gs1789.c:3: warning: cast to pointer from integer of different size
nil
arc> (gtk-hello-world)
Segmentation fault (core dumped)
The segmentation fault occurs whenever I click the button or close the window. Moving it around and resizing doesn't seem to hurt it.
Modifying inc_pt to:
void* inc_pt(void *pt, unsigned int offset)
{
return (void*)&((char*)pt)[offset];
}
I think the problem is in the connect: with mzscheme 352 it segfaults(not always, though), with mzscheme 372 it seems to work. Maybe is a bug in mzscheme 352 C callbacks. Wich version are you using?
To access some structures (such as GValue) I manually allocate the correct size with cmalloc, and to access the structure i use low level functions (such as inc_pt) wich make assumptions on the size of the structure. I program on a 32 bit machine where pointers are smaller than on a 64 bit machine, so this could (and probably is) a problem. I definetly need a better way to access C structures, but this would mean to extend Arc FFI capabilities.
Edit: i've tried mzscheme 360 and it works. The problem then is with the 64 bit.
To avoid the +(and other operators) redefinition problem we could add an optional directive to the interpreter promising that, from now on, we won't redefine basic operators.
As an example:
(promise 'no-redef)
This would let the interpreter/compiler do the optimizations.
Good idea. Not perfect as you have to annotate your code to get performance (but after all CL and GambitC Scheme work this way), but this could be tried...