freenode/#lisp - IRC Chatlog
Search
11:39:10
_death
if you're using slime, I saw this recently: https://github.com/mmontone/slime-doc-contribs
11:39:48
pjb
daphnis: with setf apply you need to put (function accessor) literally in the apply place: (let ((q (make-instance 'question)) (a (function answer))) (setf (apply a (list q)) 42)) #| ERROR: Setf of Apply is only defined for function args of form #'symbol. |#
11:40:13
pjb
(let ((q (make-instance 'question))) (setf (apply (function answer) (list q)) 42) (answer q)) #| --> 42 |#
11:41:14
pjb
engblom: you can also know what argument an operator take, just by typing (map spc in a lisp/slime buffer. Then slime will query the lisp image, and display the required arguments in the minibuffer.
11:43:24
daphnis
so i probably need to use slot-value then? and then it seems that i need to export each slot symbol in order to use the function in a new package. maybe i just put more into one package.
11:43:27
pjb
daphnis: perhaps you're doing meta protocol stuff, and using the slots directly with slot-value is the right thing in your case. It depends on what you are doing. What are you doing?
11:45:14
pjb
But again, it depends on what you're trying to do, but this seems to be a state secret.
11:45:59
engblom
Is there something that is between let and setf, so the scope is limited to the whole function rather than either having a limited scope as in let or then a global variable as in setf?
11:47:12
engblom
I am asking because I would want to write some code that would require a lot of nested let, and making the variables scope to be the whole fucntion would be handy in this case.
11:47:22
pjb
engblom: you can also define function local variables with &aux in the lambda-list, but we usually reserve this for macro expansions, since it let you add local variables without having to deal with docstrins and declarations.
11:48:29
pjb
but we prefer the (defun foo (…) (let ((x 1) (y 2) (z 3)) (list x y z))) style (foo 33) #| --> (1 2 3) |#
11:48:58
pjb
engblom: also, note how nice LET is, since it lets you bind values to the variables. So you don't need setf.
11:49:58
daphnis
i have an object representing a letter and the slots represents various features, like case, accent, name, etc. the method changes one of those features. e.g. (furnish ltr :acute) should lead to the accent slot's being set to :acute
11:50:09
engblom
no-defun-allowed: Because I would need to do (let ((some thing)) (do-something else) (let((more things)) (do-again-something-else))
11:53:46
pjb
(defun furnish (letter trait value) (ecase trait (:case (setf (casse letter) value)) (:accent (setf (accent letter) value)) (:name (setf (name letter) value))))
11:54:20
pjb
daphnis: perhaps instead of writing (furnish letter :accent 'grave) you could just write (setf (accent letter) 'grave) ?
11:55:57
pjb
daphnis: where do the trait and value come from? If that comes from a data file, it's an external source, and it should be validated. This is what ECASE does: if we get a bad trait, it signals an error. And you cannot set slots that are not in the list of cases.
11:56:45
engblom
What do you think about me using (let ((x nil) (y nil) (z nil)) (some code) (setf x something) (some code) (setf y something) ... )? That would make local variables, but not requiring a lot of nested let.
11:57:12
pjb
daphnis: now, if there was a lot of cases, or if they were "dynamic" because you'd have different classes, perhaps not know at compilation time, we could have a data structure to map trait keywords to accessors, but we would still go thru this validation and control.
11:59:14
pjb
engblom: (let* ((x (compute-x)) (y (compute-y x)) (z (compute-z x y))) (do-something x y z)) so you can have some code between the binding of the variables with let*.
11:59:57
pjb
engblom: (let* ((x (progn (something) (compute-x))) (y (progn (something) (compute-y x))) (z (progn (something) (compute-z x y)))) (do-something x y z))
12:00:22
daphnis
the traits don't come from an external source. one other thing the furnish method does is that it determines the trait based on the value (if only one trait can have that value)
12:00:23
engblom
pjb: In this case each definition of let will have a side effect: it will place a form element on a site and the reference to the element is assigned to the variable. Because of that I need to add some code between (spacers, layout, text, etc) between each assignment with let.
12:00:34
pjb
engblom: typically, when you have to initialize some complex objects, you have to use some mutation. then you can do:
12:02:26
pjb
engblom: (let ((rt (let ((rt (copy-readtable))) (set-macro-character #\a (lambda (s c) (char-upcase c)) rt) rt))) (let ((*readtable* rt)) (read-from-string "abc"))) #| --> abc ; 3 |#
12:03:11
pjb
daphnis: note that even if furnish needs to do something more, this is something you can also do by writing eg. :after or :before methods on the accessors.
12:03:40
engblom
pjb: So (let ((olt (create-select ....))) ....) would create a dropdown list on the site, and I can read the value by doiing (value olt). But to create a real layout on the site I need to add some more stuff between the form elements, so I am not able to add everything inside of a single let without some tricks.
12:04:11
pjb
daphnis: eg. (defmethod (setf accent) :before (new-accent letter) (incf *accent-count*)) (defmethod accent :after (letter) (print 'yay))
12:06:22
pjb
engblom: now the thing is that the rule of evaluations in CL are very precise. macros and special operator explicitely specify in what order, and in what scope each subexpression is evaluated, and for function calls, the arguments are evaluated from left to right. Therefore you can wrap any subexpression in a prog1/prog2/progn to add side effects before and/or after computing the subexpression.
12:07:17
pjb
And some functions are specified to return their argument on purpose so you can write stuff as : (let ((x 42) (y 33)) (print (+ (print (* (print x) 4)) (print y)))) #| 42
12:07:53
pjb
engblom: print is used like that routinely when debugging. But you can use prog1/prog2/progn and add any side effect.
12:09:45
pjb
(let ((x 42) (y 33)) (+ (* (let ((x/2 (/ x 2))) (+ (expt x/2 2) (expt x/2 1/2))) 4) y)) #| --> 1815.3303 |#
12:10:49
pjb
engblom: and vice versa. If you have an expression too complex, you can always put (defun sub (x) …) around a subexpression and replace it with (sub x)
12:11:14
pjb
(defun sub (x) (let ((x/2 (/ x 2))) (+ (expt x/2 2) (expt x/2 1/2)))) (let ((x 42) (y 33)) (+ (* (sub x) 4) y)) #| --> 1815.3303 |#
12:12:06
pjb
engblom: sexps are very easy to manipulate in the editor, and since lisp operators are very orthogonal, the code (which is actually data) is very maleable.
12:13:03
pjb
engblom: there are only expressions, and and very little syntax in macros and special operators (eg. you cannot put an expression instead of the name of a variable in a LET; but apart from those few exception, you can put any expression in place of any subexpression.
12:14:23
pjb
engblom: (if (< delta 0) (- b (sqrt (- delta))) (- b (sqrt delta))) --> (- b (sqrt (if (< delta 0) (- delta) delta))) or even --> (- b (sqrt (funcall (if (< delta 0) (function -) (function +)) delta)))
12:14:25
engblom
pjb: Thank you! Now I would only need an easy way to send stuff from vim to repl. Now testing stuff has been taking time because every time I made a change I have been (ql:quickload :my-project) in order to update repl, and I have not been able to test any function that is not external.
12:26:44
engblom
pjb: I wonder if using some vim emulation in Emacs would cause any shortcut conflicts if using Slime?
12:30:45
engblom
Is this still valid, as it is from 2016? https://fouric.github.io/posts/2016-05-20-getting-set-up-with-emacs.html
12:40:41
edgar-rft
Common Lisp is more than 25 years old and Emacs is more than 40 years old, so 2016 is like yesterday in other programming languages :-)
13:03:08
engblom
I got emacs installed. In vim I would use :set background=dark to automatically change the colors of highlightning to be readable on a dark background. Is there something similar that can quickly be done in Emacs. Right now I can not read the code with my poor eyes (when running emacs -nw).
13:08:08
_death
engblom: well, apparently color-theme is the old, deprecated, obsolete, ex-parrot way nowadays.
13:08:45
beach
engblom: I am sorry my fellow #lisp participants probably confused the hell out of you.
13:14:43
beach
It means that you don't evaluate the argument, and instead you pass a reference to a place (or an l-value).
13:15:50
jackdaniel
this is simply part of the common lisp evaluation rules, not something "natural" or obvious
13:15:59
cer-0
IIRC there are some cases when you don't apply this behaviour, take cond for example if you write incorrect code after a valid clause they won't be evaluated.
13:16:17
jackdaniel
it is related, because you present it as some natural consequence of some unspecified rule of the universe
13:16:42
jackdaniel
ACTION will back down to not confuse people hell out and leave the explanation to beach and jmercouris
13:16:52
beach
jmercouris: So, C and C++, when you call a function with an "object" will copy the object by default.
13:17:54
beach
So if you call a function with an object, the object will be copied before it is passed to the callee.
13:18:20
jmercouris
I've never been programming Lisp and thought "Man, if only I had pointers that way"
13:18:56
beach
So they have to copy in order to make sure that the number of references to an object is always 1.
13:20:32
Bike
imagine a struct that's small enough to fit in two registers. if you pass it to a function, it's passed in registers without memory being touched. if that function alters a field, it just alters a register. when the function returns, the caller registers are restored from the stack, so the struct in the caller is what it was before the call. ergo, the object is "copied"
13:21:10
Bike
C++ then adds copy constructors and move constructors and prvalues and xvalues and my god it just keeps going
13:21:23
beach
So, as Bike says, the other consequence of "copy semantics" is that a function can't modify an object that you pass to it, because it is always copied.
13:21:53
Bike
the concept of a "move constructor" is basically what beach is talking about with the number of references only being one. if you "move" an object instead of "copying" it, the old thing referring to it no longer does
13:22:09
Bike
the semantics are pretty confusing, but that's what you need to do to keep this stuff up efficiently, i guess
13:22:40
beach
Yes, it is necessarily confusing because of the lack of automatic memory management and all the consequences that follow from that decision.
13:23:26
beach
So, to me, the only sane programming model is "call-by-value" and "uniform references semantics" which is what Common Lisp uses, no matter what other people here might say.
13:24:29
beach
Granted, most modern languages do the same thing, perhaps with a few exceptional cases like Java that handles machine integers differently, or it used to.
13:25:20
beach
It is quite amazing to me the snowball effect that lack of automatic memory management creates.
13:29:55
beach
Nilby, pbj: In my opinion, it is pedagogically unhelpful to bring up the performance hack that immediate objects such as fixnums and characters use, since those objects are immutable. The semantics would still be "uniform reference semantics". At least, it is unhelpful to someone who has no clue. You can bring it up when they start asking about references to small objects like characters.
13:35:25
pjb
jmercouris: (qrt) could be not evaluated in a lazy language; or if it was a place, and if lisp used pass-by-reference (of places).
13:36:06
Nilby
Yes, but I'm not sure saying "uniform reference semantics" or just saying "pass by value" will help someone familiar with C++. I think the problem with explaining is Lisp is defined by semantics, while C is defined by memory contents and addresses. The closest I can think of to relate to C is that lisp objects are tagged unions with internal pointers which are passed by value, but may have a bunch of built-in access methods
13:36:42
pjb
jmercouris: the pass-by-reference is normally used for output or in/out parameters. In languages like pascal, modula-2 modula-3, ada, etc.
13:37:08
jmercouris
my biggest mistake in the beginning was taking concepts from other programming languages and attempting to apply them
13:37:20
pjb
in lisp since we have multiple-value results (or we can easily return lists like in emacs lisp), in/out or output parameter are not needed.
13:37:55
jmercouris
but it is not always possible to translate every word or concept from one language to another
13:38:15
jmercouris
the biggest problem is that so many programmers, myself included are monolingual (I was, at least)
13:38:26
jmercouris
perhaps we know 5, 10 languages, but they are all different flavors of the same algol dialect
13:38:37
pjb
jmercouris: in C, we use pointers to the variables to do that, so it's explicit (but also confusing is that a pointer to a variable for an output parameter, an in/out parameter, or is that just a pointer as input parameter?). So C++ has & references to distinguish it from input pointers.\
13:38:40
jmercouris
I used many languages before Lisp, and they were all the different, but the same
13:39:23
pjb
jmercouris: but of course, C++ and C++ programmers also complexify things up with copy semantics and stuff like that so that references are also used in more "subtil" ways.
13:39:38
beach
Nilby: It is hard to help people who don't bother to learn standard terminology in the field.
13:40:10
beach
Nilby: The only way I can see how to do that, is to start by teaching them such terminology.
13:42:59
Nilby
beach: Also, the first link when searching for "uniform reference semantics" is written by you.
13:43:24
pjb
phoe: well, in C copied values are limited to words pushed to the stack, so usually only numbers characters and pointers are copied. But more recently, small structures too (and returned). But in C++ whole objects and structures can be copied. And with the funny thing that if you pass an instance of a subclass, only the slot of the superclass (declared for the parameter) are copied! So you can have half objects!
13:43:58
pjb
This is all silly, and the only reasonable way to program in C or C++ is to use pointers for everything, and start greenspunning.
13:44:00
phoe
beach: yes, that's the part that is troublesome - answering "Lisp is pass-by-value" does not solve the whole problem
13:48:13
pjb
jmercouris: also, since the general relativity we know that we live actually in a 4-dimensional space, and we're interconnected 4-dimensional breads.
13:51:23
beach
I can whip something like that up in no time at all, but then there is the drudge: turning into HTML or something like that, figuring out where to put it. Insert references, emphasis, blablabla.
13:52:18
Bike
i've found markdown pretty good for writing without thinking about that stuff too much
13:53:27
jmercouris
this for example; https://nyxt.atlas.engineer/article/class-based-functional-configuration.org
14:10:57
engblom
I just got Emacs setup and want to begin coding. How I am supposed to load a package so I can access even the functions that are not exported from repl?
14:18:34
engblom
I mean, I have a project under ~/common-lisp/gpon (with gpon.asd in that directory and the source files under ~/common-lisp/gpon/src). Now when editing src/main.lisp I can not compile the whole file with C-c C-k because then it fails to compile, even thou (ql:quickload :gpon) works great and I can run the external functions after that. How do I correctly load a whole package in Emacs+slim, so I also can
14:22:28
beach
phoe: I went a bit overboard. That text could be split into two different parts with one referring to the other.
14:25:28
engblom
So what is the exact procedure that I should do to be able to send stuff over to Slime REPL from emacs? Is it first adding (in-package #:asdf-user), as jackdaniel suggested, then once (ql:quickload :gpon)?
14:26:29
phoe
when I want to hack on e.g. phoe-toolbox, I do (ql:quickload :phoe-toolbox) and then open up one of its source files
14:34:15
phoe
this way your REPL will jump into that package, and you will be able to freely access internal symbols of that package
14:36:43
engblom
phoe: Thanks! Now I think I will get an acceptable work flow. I get to test the stuff much faster, without having to export everything I write (except for what will need to be exported in the end product).
14:37:17
phoe
when you're working on code a given package, it's often beneficial to have the REPL in it exactly for this reason
14:37:53
phoe
when e.g. doing testing it's worth to jump out of that package, even if only to ensure that the tests are not using unexported functionality and that all symbols that should be exported actually are exported
14:55:27
engblom
I have been using cl-project for creating the project skeleton. Each time I create a simple project for experimenting I need to edit the asd file or I will not be able to compile with just asdf:make. Is there a better alternative for creating a project skeleton?
14:57:03
beach
I don't see the point, really. Projects are not created often, and they all have a different set of file, barring perhaps two such files.
14:58:33
beach
You need a my-project.asd file and packages.lisp file. The only thing that you can create by default is the name of the project in the ASDF file, the name of the package in the packages.lisp file, and a singe line in the ASDF file containing (:file "packages").
14:59:21
vms14
the nice thing of trying other stuff is that you learn new concepts and can apply them later
15:00:16
phoe
(quickproject:make-project #p"~/Projects/Lisp/foo") and then I modify everything else by hand
15:01:38
engblom
Yes. I with Clojure I just do "lein new whatever-name" for creating a libary skeleton and "lein new app" for making something that will even have a main function and everything ready for compiling something I can run. Lein even takes care of uploading the library to clojars so other can depend on it (in a similar way as with quicklisp).
15:03:15
vms14
engblom: taking lein as a reference, you could create a nice project builder that would be useful for other lispers
15:10:03
engblom
phoe: Right now I am doing some coding for my workplace and I picked to write it in lisp because I want to learn lisp. Previously I have been coding Clojure, but my motivation for switching from Clojure to Lisp is that programs written in Clojure are very slow to start up on Raspberry Pi. Rosewell will not work at all on Raspberry Pi.
15:13:43
pyc
engblom: Are you your own boss at your workplace? or are you working for an employer? curious how you gained the consensus to write your projects in Common Lisp.
15:17:47
jmercouris
there is not a lot of boiler plate in Lisp, no need to have a project builder beyond the scope of quickproject
15:18:46
engblom
pyc: No, I am not my own boss. This project is a smaller side project as I am not working as a developer.
15:18:59
phoe
this is a quickly hacked article, I will finish it later today - I need to run and do ELS stuff now
15:19:32
vms14
jmercouris: I guess the real reason we don't need boilerplate is the lack of libraries
15:20:38
phoe
beach: yes, and I mention that in the chapter while explaining why I coin a different name for that term
15:21:02
beach
phoe: Call-by-value means that the arguments to a function are evaluated before passed to the function. Nothing else. You can't claim Common Lisp is doing something else.
15:21:03
phoe
(mostly because the term is already abused by C++ which implies copying, and we don't do visible copying in CL)
15:22:57
phoe
I mean, I don't know how to solve the problem where I call C++ call-by-value and Lisp call-by-value and then they do different things
15:23:13
beach
I think it is a huge mistake to cater to people who don't respect terminology that has been standard for 6 decades.
15:23:37
phoe
I think it's a huge mistake to not cater to people who are in the huge majority and would simply like to understand how CL is different from C++
15:24:51
beach
call-by-value has absolutely no other meaning than the fact that arguments are evaluated before the function is called
15:25:01
phoe
yes, we do, a huge chunk of the programming world has already partially done that to the point where even Wikipedia mentions that the term is ambiguous
15:25:53
phoe
vms14: mostly because inter-human communication is a hard problem that is never solved and is never going to be fully solved
15:26:48
Odin-
phoe: He does have a point in that it's worth noting that the C(++) understanding is not by any means complete.
15:27:17
phoe
vms14: we have terms like foo that we first need to define and second need to redefine when there's other people who have their own definitions of foo
15:27:30
beach
I guess we can also say that Common Lisp is interpreted, because that's what the interaction means, right?
15:30:13
phoe
OK, updated https://gist.github.com/phoe/c48b34275cf40bece9dbc5e555555214 - should be a bit better now
15:31:45
Odin-
phoe: I suspect that part of the problem is that people now think of C as a low level language.
15:33:14
pjb
Actually lisp is also a low level language. If you remove all the macros, and use only special operators and functions… And macros, are just add-on in the standard library (CL package), or from other libraries…
15:34:36
pjb
try to use tagbody and things like (rplaca k a) vs (setf (car k) a) (ie no setf -> setq), and soon it'll feel like programming in assembler.
15:34:52
Odin-
phoe: If you think the C compiler and runtime libraries aren't doing fancy stuff for you, it becomes easy to assume that the way that system works is how things are by default and everything that works differently is doing extra work.
15:36:42
pjb
Odin-: now you can make a comparison of the low-levelness of C and Common Lisp, (and perhaps other languages), and come to the conclusion that it's a matter of libraries and of point-of-view, and that it doesn't mean much.
15:37:18
vms14
could try to explain why, and they could try to explain too, but no one will understand anyway
15:40:30
Odin-
pjb: So you'd prefer that I say "well, Lisp is low-level too" above "C isn't low-level"?
15:41:22
phoe
Odin-: they are doing fancy stuff under the hood, yes - but not in case of passing parameters
15:41:47
pjb
Odin-: well, forget about low-level. We can agree that C can be used more easily to write code for micro-controllers than lisp. There's even a C substandard for that: n1169
15:42:26
pjb
Odin-: coding for microcontroller in CL would involve, for the most practical way, writing a code generator and a compiler of a subset of lisp, like GOAL.
15:43:34
pjb
Odin-: but granted it's not strictly sensu a property of the language, more of the tools and the ecosystems. But they come with the language too, in part.
15:43:39
nij
vms14: someone may not like the answer but i think this is very true: http://www.winestockwebdesign.com/Essays/Lisp_Curse.html
15:44:26
nij
Imagine you have 20 people in your group, and you are the manager. Now imagine there are 40 groups like this in a team.
15:45:21
nij
So while lisp is better in theory, it might not be better in the eye of a project manager.
15:45:56
jackdaniel
historical data seems to indicate, that lisp may be very succesful in a corporate setting
15:46:08
pjb
nij: a project manager can easily manage the freedom of CL programmers, by defining packages to be used and forbidding other packages; and he could write the tools to check his rules trivially.
15:47:21
jackdaniel
nij: chicken and egg problem - nothing to do with the language. yet, there are capable cl programmers on the market
15:48:12
loli
nij types might offset that effect even more. From what I understand the LISP machine had types everywhere
15:48:14
Odin-
phoe: Which is the compiler arranging for something to be done in order to keep the semantics.
15:49:13
nij
I agree. I agree. I still believe there's some truth in Lisp Curse. But most likely, it might just because Lisp is not lucky enough.
15:49:26
Odin-
phoe: Which is my point - a lot of people seem to be under the impression that C's semantics come about without that.
15:50:03
loli
Might be the kind of people that are attracted to lisp. http://metamodular.com/Essays/psychology.html might help explain why?
15:50:05
phoe
but before I forget - is the stuff at https://gist.github.com/phoe/c48b34275cf40bece9dbc5e555555214 better now with regard to terminology?
15:50:06
Nilby
I was an impossible to control programmer before I used Lisp. Lisp just removes artificial barriers.
15:50:38
loli
I think the image system of CL in particular can offer a lot of great documentation and asssitant tools that should make corporate programming a lot easier
15:54:10
pjb
phoe: I would start with a paragraph or two about the fundamental difference: lisp is object/value based, while C/C++ are varable/type based.
15:54:12
nij
Btw, I'm reading LOL, and it says alambda isn't hygienic. I wonder if there's a hygienic version of it?
15:55:06
Odin-
phoe: I don't have an issue with it. I'd probably substitute 'The proper but unsatisfying answer' with something like 'In those terms, the somewhat unsatisfying answer'.
15:55:44
Nilby
nij: My story to far too lengthy, melodramatic, and not yet over. Perhaps I'll write my memoir when I can no longer write code, but more likely I'll die at a Lisp REPL.
15:55:55
pjb
phoe: 42 in lisp is an object; you can have references to it; variables don't store this object, but keep a reference to it. On the other hand, in C/C++, 42 only represent various bit patterns that can be stored in variables of different types, and that are interpreted, assuming those types to correspond to integer 42 or the floating point 42.0.
15:56:00
Odin-
phoe: Basically, allowing that we _are_ discussing it on C++'s terms while not conceding that those are necessarily correct.
15:57:16
pjb
phoe: declaring types in lisp doesn't declare the type of variables or slots, but the types of the objects that are bound to those variables or slots, and without a type declaration variables can hold objects of any lisp type; those lisp types are attached to the object, not the variables or slot that can refer them.
15:57:57
pjb
This is what gives the security in lisp: you cannot misinterpret bit patterns, or subvert them.
15:58:51
pjb
In the worst situation, in lisp, if you removed all the program and therefore all the variables, you'd be left with a heap, that you could scan to retrieve all the live objects and their data!
15:59:55
Odin-
The underlying hardware just usually has more specific support for particular operations on them.
15:59:56
pjb
The most you could do with a C heap, is to know the memory blocks allocated, but without the program and the typed variables, you couldn't know what type of object they represent (only guesses).
16:05:51
Nilby
I think C is the language that gives lispers the most trouble, because it dictates how we have to interface with things outside Lisp.
16:10:06
Odin-
Specifically, C is _specifically_ designed so that it doesn't have to deal with these issues at runtime. At all.
16:11:25
Odin-
(Which is one of the reasons it's much easier to shoot yourself in the foot using C than many other languages.)
16:12:58
Nilby
Except for things like the symbol garbage collection/tracing in dynamic linkers, runtime type information in C++,, etc.
16:16:04
aeth
You can actually do C-like abuse of the type system. You just have to pretend that you're talking to C when you're not, and use CFFI. https://gitlab.com/-/snippets/1830092
16:16:24
aeth
Not to mention that declarations are UB and SBCL with (safety 0) probably also permits such things instead of checking (but the solution is to never (safety 0)).
16:19:01
Nilby
Nice. I've see such code in implementations that can assume to know the float format too.
16:19:23
DGASAU
Nilby: while I could agree that C presents not the best IDL conventions, other languages provide worse IDL conventions.
16:21:59
DGASAU
In my experience, interfacing between any two different paradigms is possible only through something very reminiscent of C.
16:23:42
Odin-
There are plenty of things to complain about with C; the calling conventions are for the most part not near the top of that list.
16:26:22
DGASAU
All the rest usually boils down to "lets' launch XML-RPC/JSON-RPC/some-other-RPC servers and clients, perhaps bidirectional and asynchronous."
16:29:06
DGASAU
If you wish to experience what it feels, I suggest that you write something trivial on top of libpq.
16:31:26
shka_
i am seeing something unexpected with the combination of the dexador and alexandria:copy-stream
16:32:48
shka_
and then i simply use alexandria:with-output-to-file and alexandria:copy-stream to save the download into a file
16:33:33
DGASAU
Nilby: so far, the best approach in my opinion is proper IDL a la S-net, i.e. with non-recursive structures.
16:33:59
shka_
but sometimes, and this seems to happen just with the hltv, copy-stream for some reason blocks on what seems to be finish-output
16:36:01
DGASAU
Nilby: if you don't find it, tell me, and I'll probably find reference in some time.
16:37:17
DGASAU
Nilby: actually, it comes up on top in search output. Only it seems more elaborate than what I remember from the past.
16:42:44
nij
Does anyone happen to know if ambrevar will release the code of his "lisp repl shell"? https://ambrevar.xyz/lisp-repl-shell/index.html
16:45:34
Nilby
nij: Some the magic is at https://gitlab.com/ambrevar , but much of it is emacs/sly customization.
16:46:16
Nilby
shka_: I don't really know, but some servers keep the socket open, after trasmitting.
16:48:04
Nilby
nij: There's quite a lot of it in dotfiles and fof, but it's difficult to use other people dotfiles like that.
16:56:30
loli
I've found with inferior-shell I really like making quick scripts in CL, though the loading of CL as a standalone script is always somehwat painful if you don't ros it up
16:56:42
loli
yeah that's nice, I'm guessing you have undefined functions just search the bash path?
17:04:22
loli
the last feature you'd need to have a nicely working lisp shell on unix, is the ability to smoothly run stuff like ncurses windows, which it seems emacs currently can't easily
17:05:58
Nilby
You have to run it outside emacs to do ncurses, or use the thing that links a real terminal library into emacs.
17:09:12
loli
I've found for scripting that sometimes I have very short bash scripts, due to how annoying SBCL treats libraries when in shell mode
17:11:37
loli
so I have to do weird loading, that is often more annoying to figure out than otherwise
17:11:51
shka_
Nilby: i don't know, i suspect that this is somehow related to the dexador using connection pool but i am to tired to debug this right now
17:50:58
jcowan
Call by identity is good because it matches with the guarantee of putting something into a slot or variable: what comes out is eql to what went in.
17:51:59
jcowan
extending "slots" to include the car and cdr of a pair, the elements of an array, etc.
17:53:44
Josh_2
anyone had an issue with emacs where it occasionally pops up saying '<keypress> is not a valid command' meaning I have to hit the key twice? Very annoying
18:00:43
jcowan
pbaille: ##lisp is suitable for discussing all Lisps: CL, Scheme, Picolisp, you name it. It's also about the only channel where comparisons between different Lisps fits in.
19:21:52
theseb
Compilers in general strip the original high level source to an intermediate representation before barfing out assembly. Well since Lisp is a stripped down syntax that might be used for this intermediate representation, isn't it (sort of) true that compilers basically roughly just convert high level source to a lisp like lang and then implement that lisp source in assembly?
19:23:12
gigamonkey
Insofar as s-exps are a good way to represent ASTs and most compilers generate ASTs and then go from there, yes.
19:26:07
theseb
gigamonkey: to run lisp you need an evaluator...so i presume when people say they "compiled a program"...the executable literally has to implement an evaluation engine in assembly EVERY time?
19:29:11
gigamonkey
But if you take EVAL out of the language it doesn't actually change much and then you can compile a Lisp program down to assembly with no more ability to evaluate arbitrary Lisp.
19:50:08
Odin-
theseb: Well, you can think of the underlying processor's instruction set as the evaluation engine.
19:53:32
phoe
it's sorta tangential to the meat of the issue - how to pass parameters, what's copied, how to assign stuff
20:24:38
Bike
i might also mention that the only way to detect copying is eq and that it's otherwise an implementation detail
20:30:22
phoe
I kinda feel compelled to, because C++ people are gonna ask "what is copied then, because I really want to mutate this number like I can do in C"
20:39:30
ordoflammae
phoe: it seems like, if you're going to program lisp, you shouldn't want to "mutate" a number location, since that kinda' goes against the whole ideal of functional programming.
20:40:28
ordoflammae
Bike: It seemed like phoe was talking about mutating what number a particular variable is referencing without using that variable (pointers, etc.)
20:40:54
ordoflammae
I mean, yeah, you can't actually mutate the actual number (whatever that might mean), but you can mutate a particular address location.
20:41:34
ordoflammae
But you really oughtn't be doing that with lisp, you're kind of running against the grain of the entire language.
20:43:15
nij
One thing about CLIM is that.. the interface it produces is not emacs, so all good bindings aren't usable there. Is there a way to make emacs more "CLIM-like"? If so, what kind of work should be done?
20:53:38
nij
Bike: is this an attempt to make an editor in which the experience is close to a lisp machine?
21:10:45
jcowan
gigamonkey: The Chez Scheme compiler works exactly thereseb described: each pass converts Scheme to simpler Scheme, until what's left is an S-expression representation of machine language. But every stage can be run using the Chez interpreter and produces the correct result. SO if a stage is bad, you can just leave it out until you fix it.
21:13:38
jackdaniel
most notably presentations - note that when in the repl you return an unreadable object, you still can inspect it
21:42:46
Bike
when typep (or whatever) sees a type specifier defined by deftype, it uses the macro-function deftype defines to expand into a new type specifier to work with
21:45:39
kagevf
engblom: you can use invert-face RET default to toggle between light and dark mode in emacs
21:46:22
loli
for example https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node51.html they give square-matrix
21:48:46
loli
Ideally I can test my list-of on certain types like I have a list of ints and I can typep it
21:49:12
Bike
if you're defining list-of in the obvious way as (deftype list-of (type) `(or null (cons ,type (list-of ,type)))), it won't terminate
21:51:23
Bike
SATISFIES works with a global function name, so you probably can't make that work, unfortunately
21:51:48
loli
so I have to generate every type I care about? How do arrays work with their type specification
21:52:13
phoe
and there's a whole thing about array specialization that conses don't need to care about
21:52:43
loli
what a shame, so I guess I'll make a macro definition that spits out order-1 types from a forall
21:57:32
loli
we can state it takes an integer and gives back an integer, does this not use the same satifies system, or is it baked in like the array?
21:58:20
loli
yeah... satisfies sadly only takes arguments with 1 argument, Maybe I can prop something together with dynamic variables to inject it?
21:59:23
loli
I tried this before: (deftype list-of (type) `(and list (satisfies ,(is-type-of type)))). Now let us try dynamic binding
22:06:55
loli
yeah I could see a gensym approach working if you specalized the type at every single application instance you found
22:16:39
gigamonkey
CL-ASHOK: I think Conrad Barski came up with the "Made with Secret Alien Technology" and the googly-eyed alien logo before he wrote Land of Lisp.
22:18:23
loli
for those curious about the solution I have. the specalizer looks something like this. https://ghostbin.lain.la/paste/jwg6j Note that the concatenate call is incorrect because I forgot the function to coerce a symbol into a string
22:19:19
Nilby
dieggsy: block until what? you could bt:join-thread on it's taskmaster thread if that's what you mean.
22:20:14
dieggsy
Nilby: until i kill the thread i suppose --- that is what i mean, i think. how do i get it's taskmaster thread ?
22:25:05
loli
this works across packages as well, no weird name kludging due to dynamic variables right?
22:26:17
loli
how nice, we can probably make it even slightly nicer by giving it a name so the error messages are nicer
22:26:44
loli
shouldn't it complain about a not global functions ince we are just accessing the lambda inside the gethash
22:27:34
saturn2
get-predicate calls compile to make it a global function if it does not already exist
22:30:11
loli
one last question, how do you use typep with types that take types like this? I never figured that one out
22:32:45
loli
the odd thing about this form is that it takes the symbol, so I don't see how I can apply it
22:37:37
Nilby
dieggsy: You can do it, but it's not in the API, so I probably shouldn't reccomend it.
22:38:20
Nilby
dieggsy: This is probably a bad idea, but (bt:join-thread (slot-value (slot-value hunchentoot::*acceptor* 'hunchentoot::taskmaster) 'hunchentoot::acceptor-process))
22:39:23
dieggsy
Nilby: fair. i'm trying to set up a simple server for local Oauth 2.0 authentication. Basically I just need a one time server that waits (blocks), gets a request with some info, sends back "done, close this tab", then dies and other code can go on to do stuff wtih that info
22:39:58
dieggsy
i've done it in CHICKEN, but there I had manual control over the thread the web server started in
22:41:03
dieggsy
or, maybe i'm being an idiot and i just work the entire logic into the easy-handler. .... that would make more sense I think
22:41:05
loli
hmm one small error, saturn2 it seems when I compile the file it says the type is undefined, is this due to staging?
22:45:17
dieggsy
Nilby: would you happen to know if i can make an easy handler send a response and *then* shut down the hunchentoot server too?
22:45:55
dieggsy
the way i understand it the easy handler depends on the last return value as opposed to some kind of send-response function, so i don't see that working either
22:48:59
loli
I've never really gotten over the gensym issues like this in the past, since the language doesn't help. saturn2 I guess what we could do is declare a package for these functions to live, so it doesn't clash, sadly we can't gensym that namespace
22:52:08
Nilby
dieggsy: This seemed to work (bt:make-thread (lambda () (sleep 5) (hunchentoot:stop hunchentoot:*acceptor*))) or I guess you could just call (exit) or something.
22:55:44
loli
I'll complete this extension later, I at least have a plan to fix it, thanks again saturn2
23:01:08
saturn2
loli: i think there's probably a way to make it all work by using load-time-value, but it's tricky...
23:10:42
josrr
dieggsy: maybe you can use hunchentoot:send-headers; it returns a stream where you cand send de response. https://edicl.github.io/hunchentoot/#send-headers
23:26:53
saturn2
loli: okay i guess i was wrong, there's no way to make the load-time-value trick work in a deftype, it only works in a regular macro or symbol-macro
23:27:20
loli
how does that work, saturn2, I've had this issue when I tried implementing module functors into CL before IIRC
23:28:07
saturn2
well, if you need your macro to have persistent side effects, you can make it expand to (progn (load-time-value (side-effects-here)) (other-stuff))
23:31:42
saturn2
but in that case you might as well just give your custom type predicate a symbol name and use regular defun
23:32:17
loli
do hygenic macros help at all? I know Racket has a reflective tower with their macro system
23:33:25
loli
it seems a lot of research has gone into pushing hygenic macros, I think they are much stronger, but I lack enough scheme knowledge to see how they got their tower of abstraction
23:34:25
dieggsy
i dunno about stronger, pretty much every scheme will provide unhygienic macros as well cause there's some things you can't do with hygienic macros
23:35:39
loli
but the interesting thing is, he mentions in a number of his articles about better composing macros
23:35:48
saturn2
i always thought hygenic macros mostly just saved you from having to type alexandria:once-only