freenode/#lisp - IRC Chatlog
Search
22:10:23
jmercouris
I assume therefore that most of the functions and implementation is implemented in CL
22:11:06
jmercouris
so my question is, what is the minimum amount of functions you need to write to bootstrap a CL implementation?
22:11:42
phoe
you can generate the whole binary from Lisp, including what is currently generated from C as the "kernel"
22:12:08
phoe
which includes directly interfacing with the OS using Lisp, writing the required assembly using Lisp, actually assembling it using Lisp, doing GC using Lisp and so on
22:13:37
jmercouris
I don't see how that's possible, ultimately something has to go through the Potato compiler
22:13:43
Xach
jmercouris: in the 80s, there was a plan to separate the spec into "blue pages" and "yellow pages", where "blue" was the core, and "yellow" was built on that core, where blue was much smaller and yellow was all the convenience stuff.
22:13:47
sjl_
The number for Shen is 46. http://shenlanguage.org/OSmanual.htm I'd imagine CL would probably need a bit more.
22:14:58
Xach
jmercouris: beach has recently been working on things along those lines, in a researchy sense, and drmeister in a practical sense
22:15:13
phoe
but these are not 100% compatible with each other and all have been customized and maintained differently
22:15:22
sjl_
http://www.shenlanguage.org/shendoc.htm#The%20Primitive%20Functions%20of%20K%20Lambda is a better link for the Shen Kl core
22:17:05
jmercouris
how could one make a most portable language that can be bootstrapped really easily?
22:17:29
jmercouris
from what I understand, this is a topic of significant research, so I'm not expecting a hard answer here
22:18:35
phoe
in case of CL, it's complicated - CL is a sizeable language even when it comes to its basics upon which the rest can be built
22:18:42
Xach
Anyone making a "new" lisp these days has a lot of public domain source code they can reuse that is relatively portable, but it's not neatly divided into core+library.
22:20:39
phoe
CATCH/THROW and TAGBODY/GO are obvious control flow operators that are hard to construct otherwise
22:20:42
drmeister
jmercouris: It's been ready for distribution as a Common Lisp implementation for several months.
22:21:19
phoe
jmercouris: obviously it is, yes - the list of all symbols of CL package is public and we can align them into a directed graph that shows what can be implemented using what.
22:22:12
jmercouris
how could we align them into a directed graph without manually trying to implement all of CL in all of CL?
22:23:17
jmercouris
that's the thing though, can those functions be further reduced to a set of functions?
22:23:46
jmercouris
for example, could I write only 3 functions in potato that can be combined to produce all the "primitives" I need?
22:24:33
jmercouris
what if we slightly extended our spec with a couple of Lisp functions, could we get away with only two Potato functions?
22:25:51
jmercouris
drmeister: how did you decide what to implement in C++ for Clasp? I see it is a much bigger proportion of C++ than SBCL is C
22:26:22
Xach
it's a nice read on thinking about how to determine if something is "more primitive" than something else.
22:27:00
drmeister
We need to bootstrap from a C++ compiler. So I wrote whatever I needed to bootstrap in C++ until I can start using Common Lisp code during the booting phase.
22:27:20
drmeister
I also cribbed a lot from ECL - so if ECL implemented something in C I tended to implement that thing in C++.
22:28:07
White_Flame
jmercouris: I think your "I want to implement CL on top of Potato" is a bit off. You don't need to build CL on top of Potato. You can implement CL directly talking to the asm interfaces of the OS, bypassing Potato
22:28:48
jmercouris
White_Flame: I'm not trying to implement CL ontop of Potato, this is a purely theoretical conversation
22:29:17
White_Flame
jmercouris: right, but SBCL for instance isn't "built on top of C" inasmuch as it only uses C for some bootstrapping and low level runtime support
22:29:41
White_Flame
compiled CL functions in SBCL are not C functions, so I would say that does not count as "built on top of C", as it's no longer C that's running
22:33:17
White_Flame
things that I would consider "built on top of C" would be a C-based interpreter, a macro/function suite that allows you to program in the sublanguage from right within C, which expands to C code, or a Lang->C converter a la ECL
22:38:17
copec
Essentially all of the compilation to machine code (Or internal object code I suppose you could say) is done by CL based code, only the interface between that and the OS is in C
22:38:56
White_Flame
and technically that C layer is unnecessary, just easier to do it that way in a OS with a C API
22:41:03
copec
You could say they all trace their lineage back to a lisp image that was bootstrapped from ASM
22:42:43
phoe
copec: oh right, https://www.pvk.ca/Blog/2014/03/15/sbcl-the-ultimate-assembly-code-breadboard/
22:42:49
White_Flame
CL functiosn themselves have no C involved. But the API to hit the OS goes through C
22:44:33
copec
well, the internal assembler is used by all the code, but the CL code to build SBCL initially is run by the host CL implementation
22:49:10
copec
You might like https://github.com/clasp-developers/clasp/wiki/The-Build-Process jmercouris
22:50:13
logicmoo
one trick i am doing in WAM-CL is coding soemthning in prolog by hand.. hten translating ECL lisp src to Prolog to replace what i wrote in prolog by hand.. eventually will have no hand written Prolog code
22:52:50
copec
I asked beach if they had a strict subset of CL that SICL was implemented with, but the answer is nay. So it can be really confusing until you remember that once it has compiled itself enough times, the less optimized code gets replaced
22:58:14
copec
SICL is CL written in CL using all the modern knowledge of implementing a CL, according to my understanding
22:59:09
copec
Clasp is essentially enough of a CL written in C++, using the LLVM libs, to build SICL
23:21:18
copec
Also, Clasp has C++ objects working with a dynamic garbage collecting memory allocator, and drmeiste is a chemistry guy, not a cs guy
23:25:36
edgar-rft
Structure and Interpretation of Chemistry Programs (still to be written by drmeister)
23:40:14
pjb
jmercouris: sbcl shares some with cmucl. ecl shares some with kcl. ccl shares some with mcl.
23:42:00
pjb
jmercouris: there's no defined or unique kernel to CL. beach's programming sicl using the whole CL. You could theorically implement a CL using only the 35 special operators. Or just lambda. It's a silly question with no answer.
1:47:56
logicmoo
ACTION is trying to find the version of ECL that has teh least number of things implemented in C
1:49:51
dmiles
of course, aternatively i'd be happy with any full CL that has the least number of thing my interpreter would need to implement
1:57:25
dmiles
that translates purely into Prolog https://github.com/TeamSPoon/wam_common_lisp/tree/master/prolog/wam_cl
1:58:42
dmiles
to see it in actuion... https://github.com/TeamSPoon/wam_common_lisp/blob/master/t/sanity-test.lisp_load.md#compiled--umapcar-visualize
2:00:34
Bike
implementations sometimes are built in more complicated ways than like, having some lisp subset and then loading the rest of the language in like a library file
2:02:53
dmiles
there is probably even 3 levels... MinimalSupport + InitalCompiledToBackend + LibraryCompliedToBackendEachTime
2:05:34
dmiles
why i bring that is that up is that the LibraryCompliedToBackendEachTime is sometimes hard for me to tell from 2nd
2:06:31
Bike
if i'm supposed to know what these "levels" mean based on their names i uh, don't, sorry
2:37:03
dmiles
well what i should say.. is what be even more awesoem for me is if ECL wasnt bothering to make C files
2:37:45
dmiles
or better if a CL was never able to compile or translate anyhting.. if it was all merely an interpreter.. in which then i could decide where/when to compile things
2:38:16
Bike
if you have your own implementation it doesn't need to compile anything until compile or compile-file is called
2:41:16
White_Flame
while I haven't poked into your details, are you wanting to compile CL into Prolog, or interpret CL from Prolog?
2:42:26
dmiles
I have been so far compiling to Prolog (thus translating) then loading/executing the translated version
2:45:30
dmiles
the translator/compiler is mostly working but the last 29% of the code i need to write for it is still unknown.. heck it might be 50% still i need to do
2:46:48
White_Flame
the first 90% of the code takes 90% of the time. The final 10% takes the other 90% of the time.
2:51:06
dmiles
one problem was even though ECL code was helping out i still have to remove anything related to C backend
2:53:26
dmiles
would have.. so gonna try http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/impl/clisp/0.html
2:56:13
dmiles
but still open to suggestions if someone knows of a CL interpreter that 90% or more is just written in .lisp
3:01:15
dmiles
that be acceptable as long as if it expected to bytecode its system libs i can get in there and stop that
3:05:54
dmiles
even with such an interpreter .. i am still taking chunks out of its interpeter making it call my compiler first then executing
3:07:15
dmiles
Bike: in the case with SBCL i would need to ensure it could be used with its compiler completely broken
3:10:55
dmiles
impls seem to start out close to what i am starting out with and then over time they drift futther away
3:11:52
Bike
you could also write an interpreter yourself. i have most of a closure compiler (which would be portable) somewhere, i just didn't see a demand
3:12:03
Bike
the annoying parts are parsing declarations and parsing lambda list bindings, but you can sorta jank code for that
3:15:09
dmiles
in my host language i wrote a compiler and interpreter that handlers defun/defmacro/lamda etc... it parses the lambda lists and produces host language stub functions that call them etc.. i qualkify it as janky code :P
3:18:29
dmiles
Bike: "most of a closure compiler (which would be portable) somewhere" i'd love to look at it and see if i can use it
3:19:23
dmiles
ACTION arglist parser: https://github.com/TeamSPoon/wam_common_lisp/blob/master/prolog/wam_cl/arglists.pl
3:19:45
Bike
https://github.com/Bike/compilerer i haven't touched this since 2014 apparently and don't remember how it works beyond the concept
3:24:19
dmiles
well what io was thinking is it would have been a Full-CL-AST to a lessFullAST (but still CL)
3:25:05
Bike
here, like for example look at how tagbody is defined https://github.com/Bike/compilerer/blob/master/tagbody-go.lisp
3:26:10
Bike
but to compile the compilerer system you need to have like a working loop macro and stuff, here
3:27:28
White_Flame
do you compile LET into LAMBDA somewhere in there? seems like it would be the most obvious one
3:28:37
Bike
the annoying one is let* since you have to figure out which declarations go with which bindings
3:29:07
Bike
lambda is annoying because you have to pase the lambda list and also worry about special bindings
3:36:48
dmiles
i have a working package system.. readtables, arrays, hashtable .. quitre a bit of CL implemented
3:42:35
dmiles
"yeah i insert a closure of restoration of specials" this is done gensyming a tempvar savign a value.. then SETQing the specials at LET[*] time .. then SETQing back at body exit time
3:54:22
White_Flame
also you have to consider threading effects, as dynamic bindings should be thread-local
3:57:29
dmiles
i am using unwind-protect for the restorations .. but hrrm the threading side effect i realized i not actualyl done it correctly now
4:02:11
dmiles
oh right actually.. if no thread-local one had been started .. a SETQ would hit the global?
4:03:44
White_Flame
in SBCL, referring to a special var's value checks the TLS value first, and if it's unbound, returns the global symbol-value
4:03:53
dmiles
oh interesting.. after the SETQ that hits the Global i might start lettign this thread have the Binding it jsut set as if thread local
4:04:30
White_Flame
and yeah, setting a variable has to check the TLS as well, to determine where it goes
4:05:53
dmiles
(this allows otehr threads to nanoselconds later to manip the Global and it wont hurt the thread that just did the same thing
4:06:54
White_Flame
would capture the current global value into tls (assuming no existing outer binding)
4:23:24
dmiles
yeah... (let ((*x* *x*)) ...) == (let ((tempvar *x*)) (unwind-protect (progn (convert-to-tls '*x*) ... ) (setq *x* tempvar))
5:07:39
jeosol
I have a CLOS question: Do slots initialized with :default-initargs in the base case, are the values carried over in the derived class?
5:09:33
jeosol
Thanks Bike. That's what I expected, but I am getting some weird behavior. Let me check my code again.
5:17:29
jeosol
Bike: I seem to get correct behavior if I re-specify default-initarg for the slot in the derived class. It doesn't appear it is carried over
5:17:57
jeosol
This is excerpt is from PCL: This option is used to specify forms that will be evaluated to provide arguments for specific initialization parameters that aren't given a value in a particular call to MAKE-INSTANCE
5:19:33
Bike
(defclass foo () ((%slot :initarg :slot :accessor foo-slot)) (:default-initargs :slot 7)) (defclass bar (foo) ()) (foo-slot (make-instance 'bar)) => 7
5:21:47
jeosol
My code is just messy now, I need to refactor a bit for clarity. I may have chosen a poor design for my class structures.
5:33:37
jeosol
Bike: Thanks. It was a bug in my code. I had 3-level inheritance and mixed up the inherited class at 2nd level
5:46:08
jeosol
I picked a complex class structure where I am stringing a lot of concepts together (A,B,C,D), with each concept taking a few options/cases (e.g., A1, A2). I am now creating several classes: (defclass A-B-C-D () .) (defclass A1-B-C-D (A-B-C-D) () (:default-initargs ...))
5:46:54
jeosol
It then became difficult to manage the options and possibilities. Perhaps a different design would have been more tractable. When I started, I modeled this case after the stream example in Sonja Keene's CLOS book.
6:17:03
markasoftware
From the (defclass) CLHS docs: "The :accessor slot option specifies that an unqualified method is to be defined on the generic function named reader-function-name to read the value of the given slot and that an unqualified method is to be defined on the generic function named (setf reader-function-name) to be used with setf to modify the value of the slot. "
6:23:44
pjb
markasoftware: this is a special case. Functions can be named either by a symbol, or by a list where the first element is CL:SETF and the second a symbol.
6:24:54
pjb
markasoftware: note: there are other ways to implement accessors used by setf that are not functions named (setf foo), such as setf-expanders, and other implementation specific ways.
6:26:05
pjb
markasoftware: some implementation intern a symbol named |(SETF FOO)|, some put an entry in the symbol-plist of FOO, etc.
6:48:35
beach
It is interesting to see that jmercouris seems to assume a particular way of bootstrapping Common Lisp, i.e., that it has to be built from a small subset of itself. As it turns out, that is a very painful way of bootstrapping a Common Lisp system.
7:02:13
no-defun-allowed
Dibejzer: I think that is a shell problem, not a SBCL problem. Did you `chmod +x hello-world.lisp` first and run it using `./hello-world.lisp`?
7:04:00
no-defun-allowed
And most certainly, do NOT run it with sudo unless superuser permissions are necessary.
7:05:20
no-defun-allowed
If you run a program with sudo, it can pretty much do whatever with your computer, as it is run as the `root` user.
7:06:52
no-defun-allowed
It would be like rightclicking the program and selecting "Run as Administrator".
7:07:56
no-defun-allowed
These are Unix problems and not Lisp problems though, so I should probably leave them though.
7:08:04
Dibejzer
But, even "simple" actions, like entering folders quite often are impossible without sudo
7:08:49
phoe
Dibejzer: if you can't enter a folder without sudo there's usually a very good reason for that
7:09:49
no-defun-allowed
Then you should change the permissions on those directories so that your regular user can read them instead of using a hammer^W^Wsudo on them.
7:10:22
aeth
Dibejzer: you can always discuss it in #lispcafe (the off-topic channel) but that doesn't sound typical
7:10:38
Dibejzer
So, is it a normal workflow that you have to manually change permissions for so many folders?
7:11:30
aeth
pretty much everything in modern Linux/Unix is done in /home/your_name and permissions don't really come into play unless you e.g. want to make install SBCL globally (but you can install SBCL locally, I do... in fact, usually /home is much larger than / so you literally can't install everything globally)
7:12:44
aeth
Literally all of my programming is done locally, including installed language implementations. The only thing related to #lisp that I have installed in the root partition under /usr is stumpwm, the window manager, afaik
7:13:25
no-defun-allowed
ACTION still grabs SBCL from the Arch repository since that's usually close to the newest version
7:13:55
Dibejzer
I understand the concept, but will take some time to understand how to implement it
7:14:46
Dibejzer
but, for example, the script we chmoded back there was in the ~/.clisp/hello-world.lisp
7:14:52
no-defun-allowed
Installing is one of the legitimate uses for sudo, running hello world programs probably is not.
7:15:17
aeth
Installing things globally under root is dangerous because you can really mess things up if you're outside of your distro's package manager unless it's installed under /usr/local/ and even then it might mess up some things.
7:15:50
aeth
If it's under your home directory ~/ then the worst case is that it can mess up everything in home, which is only 85% of everything that's important :-p
7:16:42
aeth
no, you should not need sudo to access anything under /home unless it's under another user's home, but you only really need one "real" user who has a home
7:17:07
Bike
i don't think this is the ideal channel for untangling why your system is apparently so untrusting of you
7:19:15
aeth
Dibejzer: Anyway, the tldr is to write simple scripts under ~/bin (and chmod +x them) that set the correct environment variables (because often that's the only way to do it) and install stuff like SBCL locally. e.g. for SBCL I installed it to ~/.local I have a "export SBCL_HOME=/home/myname/.local/lib/sbcl" followed by the path to the ~/.local/bin/sbcl
8:42:22
Demosthenex
5 second opinion, total noob looking for a simple testing framework while working in repl, what to use?
8:44:39
Shinmera
if you move on from the repl you might want to look into bigger things like parachute or whatever else. there's a thousand of them out there, so pyp.
8:46:06
Demosthenex
i'm seeing quite a few, that's why i asked. looks like alot of duplication, not alot of differences.
8:46:35
Demosthenex
just tinkering with a restful api, and wanted to start capturing things i'm doing in the repl as tests
8:52:09
phoe
if you want to run a bunch of automated tests, choose one of the already existing ones - 1am, fiveam, parachute, fiasco, anything.
8:53:19
Demosthenex
and yes there is reason to use a testing framework with teh repl. i nail down a piece of code and test it on the repl, i need to record that in a test so it repeates later
8:54:31
phoe
I default to 1am in the beginning since it is so dumb that I can fully understand it after reading its source
9:18:36
Shinmera
Also, almost any discussion in here about what a best practise might be will inevitably result in hours long discussions, so I don't even know if such practises exist :)