freenode/#lisp - IRC Chatlog
Search
22:04:23
aeth
(The fast Schemes are not the Scheme with all of the libraries, at least at the moment.)
22:04:57
void_pointer
had similar reasoning here - that and a better package situation than scheme (honestly, would have preferred scheme otherwise)
22:06:34
jcowan
aeth: Chicken is plenty fast, though not as fast as Chez or Stalin, and is certainly not short of libraries
22:07:12
aeth
jcowan: Chicken is the only one where I'm not aware of a gamedev community. Racket obviously has games. And davexunit represents Guile in #lispgames and has actually made patches to Guile to improve its performance in gamedev
22:09:21
aeth
jcowan: I think that at least for the specific performance requirements of games, though, that source-to-source compiling r7rs Scheme to SBCL (with CCL as a backup implementation) will get the best performance.
22:09:38
void_pointer
jcowan: I did not think about that. That might be useful later on if I need access to various nvidia cards or older amds (got access to two intel integrateds, a newish high end amd, and well, what the pi 3 will have)
22:09:49
jcowan
I'd love to do that, although presumably one would need to take precautions around call/cc.
22:10:06
aeth
jcowan: My cl-scheme is essentially on hold until I can think of a fast, elegant call/cc
22:10:46
jcowan
I wrote a clean-room CL implementation of T years ago but had to punt on tail recursion (not commonly provided then) and call/cc.
22:10:47
void_pointer
also, might have to do chicken style MTA due to the recursion, which might not be pretty in common lisp (honestly have no idea, but wouldn't want to try it myself)
22:11:10
aeth
phoe: The way I do it in cl-scheme, it wouldn't matter. It's not like Pseudoscheme where it compiles to CL and drops the Scheme features that don't fit. It's more like... it adds a very small runtime so that it can handle all Scheme features.
22:11:44
aeth
At the moment, I use a trampoline to get tail recursion, although I guess I could make non-portable assumptions to bypass the trampoline. It's hard, though, because it's not a matter of implementations, it's a matter of implementations *and* optimization level
22:12:44
aeth
A trampoline to get tail recursion is actually very small in CL, maybe a dozen or two dozen lines, and it isn't noticably slower than actually doing tail recursion. (It probably is slower, it's just not slow enough to be detected when I benchmarked in SBCL)
22:12:53
jcowan
aeth: I think most non-CLISP implementations provide tail calling nowadays, though others here probably know better than I.
22:13:13
aeth
jcowan: The problem is that SBCL with (optimize (debug 3)) afaik turns that off, and a lot of people use debug 3.
22:13:40
aeth
And if the point of transpiling is maximum speed, the main focus will be getting it to work on SBCL
22:14:52
jcowan
"What would we think of a sailing enthusiast who wears his lifejacket when training on dry land, but takes it off as soon as he goes to sea?" --C. A. R. Hoare
22:15:05
aeth
I started out with an interpreter approach and quickly moved to source-to-source compilation, but if I return to the project I might add back the interpreter because apparently a lot of people (literally several!) were interested in the sandboxing aspects.
22:15:26
aeth
It might also be possible to (eventually) write a cl-cl with some common code with cl-scheme, to get a similar result but for CL
22:17:25
aeth
Iirc, the two things that stalled cl-scheme were (1) call/cc and (2) a mutable global lexical environment (which outside of the REPL is afaik optional, but probably nice to have).
22:17:40
jcowan
I'd like the reverse, the ability to compile CL to Scheme, but the main cost there is library cost.
22:17:56
aeth
By global I mean "global" because it would be contained to the cl-scheme runtime. I could just do something like wrap that in one big let, but then you can't add to it.
22:19:26
void_pointer
jcowan: well, if you can compile common lisp to emacs lisp, then you get pretty close since Guile can compile that into one of its intermediate representations which is scheme like and could possibly be compiled to scheme without that much effort
22:19:42
aeth
void_pointer: That sounds like a lot of performance would be lost, though. At every step.
22:20:35
void_pointer
jcowan: not that I know of. But emacs lisp is closer to common lisp than scheme is, so it should be easier
22:20:41
jcowan
CL itself (that is, the special forms) would be straightforward to compile to Scheme.
22:21:00
random-nick
guile doesn't do a really good job of compiling emacs lisp, since it doesn't have many optimisations for dynamic scope
22:21:40
jcowan
Bike: Yes, but for the purpose of providing a CL library so that CL code compiled into Scheme will get the environment it expects
22:22:14
aeth
What I want in the long run, although it's kind of on hold until I make significant progress in my game engine (I chose to prioritize that project), is a lot of languages running in one CL runtime. Starting with Scheme because it's close to CL, although it has some significant differences (nil vs. #f and '() is actually one of the more annoying ones to work with)
22:22:26
jcowan
If SICL were fully working it would just be a matter of replacing the SICL back end with one that generates Scheme.
22:22:30
aeth
Ideally, I could spin off a bunch of libraries from cl-scheme and other people could port languages that they want, like JavaScript or Lua.
22:22:41
void_pointer
if performance didn't matter at all, would take clisp which can make gnu lightning bytecode and then compile the resulting bytecode to scheme
22:24:34
aeth
jcowan: My solution is to make #f :false (although I will have to change that if I add keyword support) so I can completely use the host CL's lists without issue. This requires every CL predicate to be wrapped when called from Scheme, though.
22:24:46
aeth
jcowan: It has been a long time since I read about Guile's solution but I think I was inspired by it
22:25:40
aeth
In case anyone is wondering, this appears to be the page: https://www.emacswiki.org/emacs/GuileEmacs#toc7
22:26:24
aeth
jcowan: I think it's actually easier to do such a thing from a Scheme host instead of from a CL host
22:27:04
aeth
I want to use as many CL built-ins as possible, for performance. Anything that's built-in will probably be faster than anything I write myself. Or, at worst, equally as fast and much more concise to write.
22:27:29
aeth
It will also leave a clear path for using Quicklisp libraries. Just wrap them the same way as CL built-in functions/macros.
22:29:02
Bike
sicl is written in common lisp, so you need a common lisp implementation to build and to load it
22:29:07
aeth
As for the performance of :false, I think the disassembly is essentially identical in SBCL with comparisons to NIL. It just compares to a different magic number, representing :false, than the magic number representing NIL.
22:29:31
aeth
Any performance penalty would be at the conversion barrier when interfacing the two languages.
22:30:10
jcowan
Chicken, e.g., is distributed with both source code and compiler-generated C for that reason
22:34:05
jcowan
aeth: You're saying that (if (eq? foo :false) this that) compiles to the same thing, modulo a constant, as (if foo this that) in SBCL?
22:35:21
jcowan
Almost any Scheme would trivially provide all the SICL primops, from the list I saw, and it would already have a GC and so on.
22:35:38
aeth
(defun foo (foo this that) (if (eql foo :false) this that)) (defun bar (foo this that) (if (null foo) this that)) ; the only difference in disassemble is one line: ; 302: 4981F86FA94F20 CMP R8, #x204FA96F ; :FALSE vs. ; 92: 4981F817001020 CMP R8, #x20100017 ; NIL
22:36:49
void_pointer
Bike: I guess one criteria is whether it can, if you just download the source, whether it can be built without having to already have a built version or another common lisp implementation
22:36:54
rme
on some ccl ports, nil is just a really popular constant. on other ports, it has its own tag.
22:37:16
void_pointer
Bike: GCC, for example, requires a working C or C++ compiler to already be there
22:39:01
aeth
(defun foobar (foo this that) (if (not (eql foo :false)) this that)) (defun barfoo (foo this that) (if foo this that)) ; essentially the same, it's still testing against :FALSE or NIL
22:39:09
jcowan
ACTION remembers when NIL was internally represented as all-bits-zero and there were zeros at locations 0 and 2
22:39:57
void_pointer
Bike: depends on who one asks. There is this one project https://gitlab.com/janneke/mes whose part of a collection of tools whose goal is to bootstrap GCC from a small assembler (assembler to build minimal scheme implementation and C compiler (in scheme) to then build tcc and then try to build gcc)
22:41:13
aeth
There is an idiom where :false as #f is going to cause problems, though. You can type something in CL as (or foo null) and it'll behave exactly as you would expect it to behave. Either it's false or it's a foo.
22:43:02
jcowan
if you all you need for your new chip is an assembler sufficient to assemble a (macro-assembler version of) Scheme, you are in business
22:44:29
Bike
ok so anyway, clasp's problem is that it mostly builds from C++ without lisp, and along with a few other things this makes the build a stupid process
22:44:31
aeth
jcowan: I think "esolang" is a bit... lacking of a term. There are two kinds of esolang. "artistic/simplistic" ones and "malicious" ones. Brainfuck is a simplistic one, not an actively malicious one (although the way it jumps makes it hard to do anything useful)
22:45:36
aeth
Bike: The problem is that everything eventually becomes mathematically useful. Ask pure mathematicians.
22:46:05
aeth
(Well, that's a similar case... where pure math gets applications in comp sci or physics)
22:47:40
Bike
brainfuck didn't "become" useful anyway, it's essentially identical to P'', invented in 1964
22:48:22
aeth
I tried writing a CL in Brainfuck, but then I realized that it's at least 10x harder than writing one in asm, and asm would at least be useful to someone.
22:49:18
void_pointer
Bike: sounds like clasp's bootstrapping situation isn't that bad, unless it takes forever as C++ often does (now reminded of how bootstrapping Guile can take well over an hour)
22:49:24
aeth
Writing directly to some VM's register machine or stack machine is probably considerably easier than BF.
22:49:44
Bike
it would be far more sensible to build from something else, and i've done some work in that direction, but that's still hard
22:50:48
aeth
I think the only way to have useful BF as a compilation target is to move the world around some central area (so it's always close by) as you walk through the BF tape. Or perhaps have two BFs talk to each other.
22:52:41
aeth
C++'s focus is on adding very many "zero cost" (at runtime! not at compile time!) abstractions.
22:53:37
aeth
An extended macro system could probably do something very similar to what C++ does in a Lisp without the massive time penalties of C++ compilation.
23:01:14
rme
It bootstraps by writing a minimal image file (which it constructs in memory), and alsocompiling (or cross-compiling) additional source files that comprise the rest of the lisp. You can then start the bootstrap image, which will then load those fasl files. Then you save an image of the lisp you just made.
23:10:22
phoe
so basically, as soon as someone can create a minimal image file outside CCL, then CCL becomes sanely bootstrappable?
23:21:29
phoe
I looked at CCL's bootstrapping process some time ago and I wouldn't call it mad, if that's what I accidentally implied.
23:24:17
aeth
Ahah! At least in SBCL, I can do this: (deftype false () `(member :false)) and then these are essentially identical: (defun foo (x) (typep foo 'nil)) (defun foobar (x) (typep x 'false))
23:24:39
aeth
At least one more point in favor of using a keyword or symbol when embedding a language that requires separating false and '()
23:26:25
aeth
Ahah! At least in SBCL, I can do this: (deftype false () `(member :false)) and then these are essentially identical: (defun foo (x) (typep foo 'null)) (defun foobar (x) (typep x 'false))
3:19:37
jcowan
perhaps sbcl stands for sanely bootstrappable common lisp, at least some of the time?
8:39:58
shrdlu68
flip214: How did you solve the multithreading thing where different threads were writing to a stream?
8:41:19
flip214
I was stumbling about having :if-already-exists :append and did look at old data in that file.
8:57:53
jeosol
flip214: had similar problems with my parallel code, and used with (bt:with-lock-held ...)
9:17:54
MrMc
I am trying to use parenscript with the Chartist javascript library how do I get parenscript to emmit new Chartist.Line('.ct-chart', data);
9:20:17
MrMc
The challenge is that this is wrapped as a function returning new Chartist.Line('.ct-chart', data)