freenode/#lisp - IRC Chatlog
Search
15:36:11
phoe
jcowan: not anymore, I think. I've already raged a little too much over the quality of their code.
15:38:46
jcowan
Out of curiosity, does anyone know what CL is used for at Google? When I was there (2007-10) it was no more than a rumor and a style guide.
15:41:14
jcowan
I note that the published Intercal style guide ends in "When to use Intercal: Only if you absolutely have to! Good grief, has it really come to this?"
15:44:10
pjb
soma1257: the only career advise we could give you is to follow Paul Graham's steps: start up a company, write a nice web app in clisp, well your startup to yahoo or google for $100+M, become venture capitalist.
15:44:41
pjb
shka: win obfuscation contests, ensure long term employment, answer silly questions, and more.
15:45:31
pjb
soma1257: but if you want to earm more money, learn kotlin or swift and write mobile apps, it's where the easy money is nowadays.
16:13:50
rpg
aeth, Shinmera: you can build a lisp image with ASDF for delivery as an application. I think there's enough difference between systems that ASDF will *not* build you a command-line executable. It will get pretty close, though.
16:14:42
rpg
drmeister: I've used dribble in non-interactive experiments, or experiments that produce a truckload of output that I need to grovel over later.
16:15:09
rpg
Typically only for not-so-well structured systems where I don't want to bother figuring out how to redirect output myself.
16:16:05
rpg
Shinmera: But I thought the question was about executable delivery, for which source delivery is not necessary, and might even be A Bad Thing.
16:16:37
Shinmera
I think aeth wanted to have things as a single source file for better optimisation.
16:17:14
Shinmera
As for binary deployments using ASDF, I think it's currently the best way to create deployments for Lisp applications.
16:18:43
jcowan
ACTION mourns the loss of Interlisp culture with its image/logfile program representation
16:24:30
rpg
jcowan: ? You can still build images for your programs. It's not clear what are the limits on shipping them around, though, because of possible incompatibilities with shared libraries where you deploy.
16:24:58
rpg
Or do you mean something like Smalltalk, with its "there is no source file" philosophy?
16:26:59
rpg
I had to work with some code from... that expert systems vendor -- I think an outgrowth of LMI or possibly symbolics -- they had no source files. I really hated it, because they used it to chain you to them
16:29:54
jcowan
(I worked for a while with Lyric, the first full implementation of CL-IL coexistence)
16:31:32
rpg
I can't imagine working without `diff`, imperfect though it is. Or the ability to work with git. Using jupyter now, which has a similar feature (bug?)
16:34:01
jcowan
It's clear from reading the JLS that the Java people expected classes to be stored in a database in production, rather than in the file system.
16:36:10
beach
rpg: Things like diff and git sort of work, but only because we represent everything as text. And even then, it doesn't work that well. It would be interesting to investigate how similar tools could be created for more complex data like structured documents, graphs, etc.
16:38:36
beach
rpg: But you are right of course. Given that we do not have any tools that work on more complex objects, then it is hard to imagine doing without those tools today.
16:39:14
rpg
beach: Agreed, but I am pessimistic since how long has there been microsoft word? And I still can't put a word document in git and track modfications.
16:40:47
pagnol
is there a way to just export/publish everything when defining a package with defpackage?
16:41:35
shka
pagnol: you CAN iterate over all symbols in package and export but i have no idea why would you want to do that
16:42:56
jcowan
you could write some git porcelain that unpacks .docx/.pptx/etc., which is basically zipped XML, and store the individual files, reassembling them on checkout.
16:43:07
fourier
but it is self contained and you just give someone else a file and he will read these modifications
16:43:11
jdz
fourier: the "track changes" thing does not exactly work when different people do changes independently.
16:43:14
rpg
my colleagues all make horrible directories with my-final-report-v287.docx and similar snot in them.
16:44:51
fourier
for simultanious access ms invented sharepoint. so everyone who is workng with management documents has to use it in big corps...
16:44:53
rpg
jcowan: It's not that, it's because they can't easily pull out old versions to diff them: it's easier to leave all the versions around and use compare revisions.
16:45:21
rpg
jcowan: My company is (a) not hierarchical and (b) staffed substantially with CS Ph.D.s who are just fine with tree structured directories, thank you very much
16:46:41
rpg
but this is a big detour from talking about interlisp and smalltalk! Just my explanation for why languages with no file representation scare me!
16:47:16
fourier
rpg: not really, it has a lot of stuff, but what I've used it is to work with the documents simultaniously with other managers. so they were normal doc and excel documents, just with versions, checkin/checkout like in vcs
16:47:21
jcowan
I have in fact taken Word documents, unzipped them as described, made global changes to styling, rezipped them, et voila.
16:59:16
jcowan
beach: I note that the beginning of that document says Unix was designed to run without an MMU, but this is not true
17:03:05
cgay
ACTION is just throwing out the name of a random expert systems provider related to Symbolics and no specific knowledge of their lack of source files or lack of lack of source files, as the case may be.
17:03:27
pjb
jcowan: it's true that early unices could run without a MMU, and the first one didn't have one. THe PDP-7 didn't have a MMU, and The 11/20 lacks any kind of memory protection hardware unless retrofitted with a KS-11 memory mapping add-on.
17:20:15
pjb
rpg: the problem is that files are sequences of bytes (or at best, sequences of characters); therefore diff provides you with a difference in characters, which is not meaningful for software development purposes. Then you have all kind of problems, such as commits with only indentation changes, or worse, commits mixing indentation changes and semantic modifications.
17:21:08
pjb
rpg: I'm not saying that a system built on structured code "data bases" would be better, but it has at least an opportunity to make it better. At least, indentation is left to the pretty printer…
17:44:44
semz
Does Slime use the FFI internally for interprocess shenanigans? I'm trying to figure out the cause of a segfault.
17:44:58
cgay
Isn't it all a matter of tools? With text files you can always apply a reparse+pprint step before diffing, for example. Or parse and diff the ASTs or whatever. It's just that there's a boatload of text-based tools lying around and the other tools would necessarily be more language-specific, I think? (Sorry if I missed some context.)
17:50:30
semz
Xach, are you somewhat familiar with Slime's internals and could you help me track down the cause?
18:00:32
semz
phoe: ECL seems to catch the segfault, so I don't think there even is a dump. It doesn't crash itself and just returns to the toplevel. Then (again, only sometimes) the connection dies out of nowhere.
18:02:50
khrbt
semz: can you share details on how you set up your system so someone can try to reproduce what you are seeing?
18:15:16
semz
khrbt: Sure. It's a clean install of Emacs (25.3.1, from Gentoo's musl overlay), Slime (2.20) and ECL (16.1.3). Musl is on 1.1.19.
18:38:02
rpg
cgay: I think you were right: intellicorp. They did a bunch of work in the petroleum industry back when I was working at the Honeywell labv.
18:40:30
semz
rpg: It was the easiest to get. Glibc can't statically link so the bootstrap binaries for say SBCL don't work on my system.
18:40:55
phoe
get your ECL ready to load slime, attach a debugger to it, try loading slime. you'll get the sigsegv and will be able to print its stacktrace.
18:42:38
rpg
semz: I think you will find that you will be happier using Clozure CL or SBCL. ECL is a tool with a very specific niche and in my experience does not work well as a general purpose CL implementation.
18:43:35
rpg
It has many idiosyncracies, and code of mine that really exercises CL makes it error out all the time, despite working successfully on ACL, CCL, and SBCL.
18:49:43
Xach
If the primary goal is to get CL stuff done, ecl can be a tough start. But if you're playing around and aren't under time pressure or whatever, trying ecl and reporting bugs is helpful in making it better.
18:59:38
rpg
Xach: True, but I guess I would suggest getting your footing using a more normal CL would be a better experience.
19:03:17
rpg
puchacz: It's maintained, but for whatever reason, it hasn't been possible for the project to manage a release in years and years.
19:04:04
rpg
I don't have the energy to build it from source, but I hear that the head version is much better than the release
19:04:12
puchacz
SBCL has monthly releases, ABCL maybe once a year, clisp, no release for a long time as you say
19:05:19
rpg
CCL is also quite active. ECL is still, AFAICT, recovering from loss of its main maintainer and need to restructure as a project
19:11:03
pierpa
Many years ago to build clisp all the energy required was to type 'make'. Is it not so anymore?
19:16:10
Xach
pierpa: I haven't found that to be the case for many, many years. I always have to fetch some extra libraries.
19:39:01
puchacz
btw, is ABCL good enough for 24/7 server? I know SBCL is a default go-to Lisp for this, but if I ever need to interact with large amount of Java?
19:39:51
jcowan_
pjb: Yes, if you count PDP-7 Unix. The PDP-11/20 ran only Mini-Unix, not Unix itself
19:40:01
phoe
puchacz: ELS 2016 had a lightning talk where AFAIR there was a Java application deployed to production with ABCL included. AFAIR it was a server application, but I might not know the details.
19:40:59
rpg
puchacz: I have found ABCL to be substantially slower than conventional lisps. I have used it very successfully as a way of scripting a Java application, but I don't think I would use it as my "main" lisp
19:43:07
puchacz
rpg: yes, I think it is slower especially around string processing. I parsed logs with it.
19:45:58
puchacz
ABCL is also the only Lisp I can have at work.... it is just jar to be downloaded. but I can't have quicklisp because our proxy is authenticated
19:46:26
puchacz
in Eclipse for Java I have to put my corporate username and password for updates to work etc.
19:47:23
puchacz
it would help if we had a single directory with all current quicklisp bz2 or whatever libraries
19:49:50
Xach
puchacz: quicklisp can export library sources into a directory and set up for loading without quicklisp.
19:50:47
Xach
puchacz: i mean make the bundle on a connected quicklisp system, transfer it to the unconnected system.
19:51:34
phoe
Xach: do you make it possible to somehow download a whole quicklisp dist at once via a web browser?
19:52:20
phoe
welp. a link to a whole archive file would be fun for that since web browsers are allowed via corporate proxies.
19:56:41
didi
Can I define a structure of :type list that the last slot is a rest at some point? e.g. (mystructure-rest (make-mystructure 1 2 3 4)) => (3 4)
19:58:11
jcowan
ACTION is amused by how ./configure checks for fork(), and if that succeeds, checks whether fork() actually forks.
19:59:10
Bike
(defun make-mystructure (a b &rest r) (list* a b r)) (defun mystructure-a (o) (car o)) (defun mystructure-r (o) (cddr o))
20:01:00
pjb
I would use %make-mystructure because you may have other options such as :named, etc…
20:07:09
pjb
there is at least one html processor written in CL, but I don't remember its name. Probably too old, and not supporting javascript, so basically useless.
20:47:38
aeth
rpg: Shinmera's right. There are three levels of compiler information. Function (compiler can do everything), compilation unit (compiler can do fancy tricks), everything else (compiler can't do that much). Generally, file == compilation unit, so putting everything in a file *should* in general make things faster. It could slow some things down by adding type checks, but, in general it's better for a final executable.
20:49:15
aeth
It also seems to not work with certain libraries. I'm going to have to think about how to replace them to make it work. At the moment, it only works if I load the all-in-one file after already loading the system normally, because CL culture overrelies on fragile global *foo* variables that can break in cases like this, and in threads, etc.
20:51:08
aeth
Dynamically scoped globals slow down your code by killing pretty much all compiler optimizations. And they are problematic enough that they have to be earmuffed by convention.
20:51:52
rpg
aeth: Is putting everything in a single file equivalent to WITH-COMPILATION-UNIT, or not? I don't claim to know.
20:52:04
aeth
They're not particularly problematic in single threaded programs when earmuffed. They are absolutely problematic when not earmuffed because you'll accidentally have a dynamic variable when you expect a lexical variable if you do not earmuff.
20:52:37
aeth
They *do* kill compiler optimizations, though, because they could be literally anything.
20:53:09
aeth
I'm not sure even a compiler with global program analysis could make dynamic variables fast because you could redefine a function at runtime or in the REPL or whatever to suddenly set that value.
20:54:58
aeth
I used to use globals as a quick hack when I didn't want to (at the moment) rewrite the function signature of a bunch of functions along the call stack, but... I got unexpected results because they don't necessarily sync between threads the way I thought they might. Now I essentially never use them, except for input/output/etc. where a bad value isn't the end of the world.
20:58:34
aeth
Well, I can use them *in the REPL* rather than in the program, such as (defparameter *window* (function-call-that-returns-a-window)) and then I can use method calls on the window object
21:00:20
aeth
didi: Iirc: defparameter overwrites it, though. If I do defvar, wouldn't the first one have to be the defvar, and then subsequent ones setf?
21:01:10
didi
aeth: Yeap. It's more of a concept thing, I read. defparameter if for program definitions, defvar for variables.
21:01:47
aeth
In the REPL I always use defparameter because defparameter is what I expect (especially since I mostly use backwards history search in the REPL)
21:02:13
onion
hm yeah. this is also something that writing a C lisp runtime with SDL , could solve. for eg. it would take care of any globals that need to be around, like the SDL window, audio context
21:02:27
_death
when there's pervasive context, use of special variables makes sense.. also makes for a much better experience when using the repl.. other languages tend not to have special variables, so there's no comparison
21:03:52
aeth
onion: I put the things that need to be around in one window object (e.g. the SDL window, the GL context, etc.).
21:05:16
aeth
It's very, very easy to wind up with way too many things in general, so I heavily use both CLOS objects and structs all over the place, and probably need at least twice as many as I do use because there are just too many things. I think at one point, one function said something like "function foo expects twenty-one arguments but only twenty were provided", but I think I've halved it since then
21:05:44
aeth
Yeah, globals could probably help, too, but it doesn't actually tidy up the mess: it puts the mess in 20+ globals
21:07:29
onion
aeth: i think that is what i will do as well. i only really need the GL/AL context and SDL stuff
21:07:49
onion
...not that any apps make more than one SDL window or anything else... overdesigned i think =)
21:08:31
aeth
onion: That's one reason I write my own stuff instead of using libraries. Libraries have to handle every case, my own stuff on the raw CFFI only need to handle my case, and are about equally verbose.
21:08:45
aeth
More than one SDL window? Nope! I can say that will absolutely never be permitted, at least for now.
21:09:22
aeth
If you handle more than 1 use case when there is more than 1 possibility, you will never get past that area, and you probably won't test all code paths.
21:09:24
onion
im just saying it seems like an overdesign for SDL2 to just about force globals "just in case" someone needed more SDL in the same thread
21:10:15
aeth
_death: In CL, large seems to start at around 7k. I'm absolutely astonished when I see some CL things above 100k (SBCL?) because that's probably equivalent to about 5M in other languages.
21:10:49
aeth
Although I expect that when it's finally working it will be around 25k. I spent about 2 years around 5k, though, because with macros it's hard to actually have forward progress in line count.
21:13:26
aeth
But it's not really line count in CL, it's what you're doing. There's a lot of stylistic freedom.
21:14:01
Shinmera
Doing a primitive line count on my projects directory (which doesn't have everything) I get around 200'000 lines. Neat.
21:16:41
aeth
Running "cloc ." on my outdated SBCL git checkout (cloc cuts out comments and blank lines, but not the docstrings) says SBCL is 401130 lines of Lisp and 26921 of C and 3817 of C headers and 3681 of sh and 2382 of asm
21:19:43
aeth
Well, of course most Lisp in the wild is Emacs Lisp, and probably a lot of that eventually makes its way into Emacs itself.
21:20:16
aeth
(and iirc cloc doesn't distinguish between EL and CL, so it might not be 100% accurate for projects that have Emacs modes in their source tree)
21:20:54
aeth
Emacs Lisp isn't particularly well-written Lisp, though. In general. I think a lot of it is working around the limitations of the language, and a lot of it is Lisp written by people who have no CL or Scheme experience.
21:21:09
aeth
I'm not sure how the standard of the core compare to some of the horrifying add-ons whose source I've read, though
21:22:33
aeth
If you're normally a C programmer and you write an EL file, you're probably not going to abstract as much as a seasoned CL programmer writing a CL application. And many common abstractions might introduce too much of a runtime penalty in EL vs. in SBCL or CCL.
21:24:01
aeth
If you know how to make an AOT compiled CL perform, you can get away with writing a lot of "zero cost" abstractions that probably don't work in other Lisps.
21:25:33
onion
i did cl-bench on SBCL and ECL the other day , i dont see what it gains; they could just compile with SBCL. =)
21:25:55
aeth
I generate GLSL strings from CL macros at compile time. It probably wouldn't take *that* much to also support C given the major similarities.
21:29:10
aeth
onion: SBCL is an order of magnitude more popular than CCL, which is an order of magnitude more popular than the rest.
21:31:07
aeth
Personally, I only try to support SBCL, CCL, and ECL. The other popular FOSS ones are CLISP and ABCL, which are both problematic in various ways when making assumptions that work on the rest (especially on SBCL and CCL). And for LispWorks/Allegro, well, they can always pay me if they want me to support their really expensive implementations. Or at least give me free copies.
21:31:58
aeth
It's probably hard to judge the relative popularity of the long tail but still used implementations (ECL, ABCL, CLISP, LW, Allegro)
21:38:28
aeth
Oh, I might have been unclear. SBCL is an order of magnitude more popular than CCL, which is an order of magnitude more popular than any remaining individual implementation... Not necessarily an order of magnitude more popular than all of the rest combined.
21:39:27
aeth
And no matter what it'd probably undercount commercial implementations, which are kind of in their own world.
21:39:32
void_pointer
When I first heard that, I found it quite surprising. I was under the impression that the gaps between 2nd and 3rd was much narrower, and 1st and 2nd a bit narrower
21:40:06
aeth
void_pointer: Things were probably narrower 10 years ago when CLISP was extremely popular. Years of no release has made it decline significantly afaik
21:40:37
_death
aeth: if you think about the primary feature of ECL, being embeddable, then the number of users (developers) is also more tricky to determine
21:41:01
void_pointer
that would explain it. I had tried picking up common lisp a first time back in 2013 and then put it down until just late last year
21:41:20
aeth
I'm guessing 10 years ago CLISP was up there with SBCL and LW might have been up there as well
21:41:34
aeth
It's really hard to compete with SBCL, though. It's both the fastest *and* the most informative.
21:41:54
aeth
(In general, of course. I still catch things that SBCL tolerates and CCL does not, for instance.)
21:42:24
aeth
jmercouris: CLISP is a bytecode implementation, so it's probably the first to every new platform. (Not a big deal when everyone is on x86-64 or ARM, and maybe RISC V in the future.)
21:42:28
jmercouris
aeth: I find it the other way around, SBCL is constantly complaining about things that CCL accepts unquestioningly, what platform are you running on?
21:43:21
void_pointer
ECL has some major advantages when working with lots of C code back and forth. That is one area where SBCL has some disadvantages
21:43:36
aeth
It also takes a *long* time for accurate and up to date information to spread. A lot of old material tells people to use CLISP or the free LW.
21:44:05
aeth
The common wisdom today is probably something along the lines of: "Try SBCL then CCL then ECL in that order." That wasn't the advice from 1998 to 2010. And those sites and books are still there.
21:45:18
aeth
Fedora has SBCL and ECL, and maybe one or two more obscure ones. But does not have CCL.
21:45:21
void_pointer
phoe: yes, in its various facets. Different GC helps a lot, even though it hurts performance in many ways.
21:45:34
aeth
Pretty much every Linux (or other Unix) distro that has a packager who cares about CL is going to have SBCL
21:45:35
phoe
aeth: I do not think any Linux has CCL in its repos. not from the popular ones at least.
21:46:29
void_pointer
if for no other reason than to make sure my code runs on multiple implementations OK
21:47:15
void_pointer
GNU/Linux, but the project I am working on would target other OSes as well - specifically Windows, Max OS X, and possibly FreeBSD
21:47:16
aeth
I use roswell to get the latest SBCL and ECL and CLISP (hah, like they'll update it), and to get any access to CCL, ABCL, Clasp (roswell fails to compile it, which is annoying because the failure happens after at least 10 minutes; maybe it works now), etc.
21:47:47
aeth
I develop on Fedora's SBCL, though, because it's recent enough. Fedora seems to treat every SBCL release as potentially breaking, so it only updates when the distro updates, which is every 6 months. Current enough, though.
21:48:27
phoe
void_pointer: just grab a ccl package from the website and ln /opt/ccl/lx86cl64 /usr/bin/ccl
21:49:02
void_pointer
between that and having to worry about both amd64 and arm, I have to stay rather flexible with respect to implementation still
21:50:36
didi
ACTION keeps forgetting `:initial-value nil' and no :initial-value are different for reduce
21:51:38
aeth
I've been waiting for a cheap (< $250), low power RISC V for years at this point (lowRISC used to say that it would release sometime in 2017). It's close enough to MIPS that I think CCL and SBCL will support it fairly quickly.
21:53:59
void_pointer
funny thing, just ordered one yesterday - pi 3 B+. Getting it for common lisp development actually. Want project to run on low end ARMs with decent enough performance. If it can work well enough on it, then it will work quite a bit better on higher end ones. Also, reduce ISA assumptions
21:54:29
jmercouris
void_pointer: a good way to test how good your code is to run it in a VM with low resources
21:54:56
jmercouris
it is very easy to deploy, and you can use something like vagrant with some provisioning system behidn it
21:54:59
aeth
I make one architecture assumption: 64-bit, with a large enough implementation fixnum size (60ish is fine; this is something that both 64-bit CLISP (48ish bits) and ABCL (uses 32-bit int) fail afaik)
21:55:09
void_pointer
aeth: on risc-v, more likely to see a cheaper board from sifive soon than lowrisc, I think
21:55:51
aeth
The problem with 32-bit is that the size of everything depends on fixnum, and 32-bit is a *much* lower fixnum size. Also, single-floats are boxed. There goes the performance of anything that uses single-floats.
21:56:08
void_pointer
aeth: I have used 64bit SUSE on a pi 3 already (port had a lot of work left to do, sadly)
21:56:33
aeth
I write double-floats with care, and at least SBCL knows that it doesn't have to box them if they're stored in arrays (or structs) of the right type and accessed the right way. I don't write single-floats with care, because that would be annoying.
21:56:55
aeth
So while stuff I write that use floats could run in 32-bit, it will absolutely destroy the GC if in a hot loop
21:57:07
void_pointer
jmercouris: a VM is useful for that, and I do plan on using some VMs for some more extensive tests across more processor families
21:57:53
void_pointer
jmercouris: though, one thing a VM doesn't provide, is a physical GPU, though admitedly the pi's is quite pathetic (which in some ways is ideal for what I am working with)
21:59:40
aeth
jmercouris: The big CL program I'm writing is a game engine. It's not CPU bound, it only uses about 2% to 8% (mostly on the low range) of my i7-4790k (might already be too slow for a pi3) because it runs the logic at 100 FPS and the rendering vsynced. (I don't have networking yet, but if used on a headless game server, it'd probably use a lot less CPU because the rendering takes up a lot of the CPU)
22:00:00
aeth
But it's a game engine, or possibly a game framework. Depends on how I market it in the end. The CPU overhead has to be low because that means that the users can do more things with it.
22:01:26
aeth
I'm told that the CPU% thing might not be 100% accurate because the modern computer might go into a lower power mode. And my engine might be low enough in CPU usage that it might send the computer into low power mode. Idk.
22:01:34
void_pointer
on a pi 3, it might work ok if game logic and graphics run on separate threads
22:02:03
aeth
FPS is too influenced by the renderer, and FPS only really tells you when it's under the cap.
22:02:38
void_pointer
aeth: funny coincidence, but that is the sort of project I am working on as well
22:03:34
aeth
void_pointer: Common Lisp seems to be increasingly popular, at least on Freenode, for this sort of thing. I even see it show up from time to time in #reddit-gamedev, not just in the Lisp-specific #lispgames (although I haven't seen it in #gamedev yet)
22:03:49
aeth
I guess people want something Pythonish, but without absolutely terrible performance for this sort of thing.
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?