libera/#commonlisp - IRC Chatlog
Search
19:33:58
Catie
There's classes of bugs that exist in C that don't exist in Common Lisp, but it's still plenty possible to do insecure things by programmer error. You won't smash the stack by overrunning an array (although it might be possible with (optimize (safety 0))) but you could still write sensitive data to to disk or something
19:36:47
Shinmera
you can also still do rowhammer no problem if you find a vector to write to memory repeatedly.
19:42:28
Shinmera
And then, certain *implementations* are certainly much less secure than other languages' implementations, simply because they let the programmer write very unsafe code that can be exploited :)
19:54:43
dlowe
except for removing pointer arithmetic I don't think CL has much to offer in terms of security.
19:57:24
dlowe
a first-class environment is an encapsulation of global state. It would be like passing all of the global state to the evaluator
19:58:21
dlowe
so, for instance, you could create an environment with no access to files or network, and evaluate your user input parsing code there
20:10:27
hashfunc77a
ok i'm having a brain fart. what is the best way to get a nested list from a list based off of a certain keyword's value within the nested list?
20:13:27
hashfunc77a
if i have the list: '((:WEEK 1 :DAY MONDAY :DATA ((BEEP) (BOOP))) (:WEEK 1 :DAY THURSDAY :DATA ((BOOP) (BEEP)))) and i want to get the :DATA of nested list '(:WEEK 1 :DAY THURSDAY... how can i do so?
20:15:18
Catie
If you know which position the list is at you can use NTH. Otherwise you'd have to search the outer list based on some criterion
20:16:06
pjb
(defun select (indicator value plists) (remove-if-not (lambda (plist) (equal value (getf plist indicator))) plists)) (select :day 'thursday (select :week 1 '((:WEEK 1 :DAY MONDAY :DATA ((BEEP) (BOOP))) (:WEEK 1 :DAY THURSDAY :DATA ((BOOP) (BEEP)))))) #| --> ((:week 1 :day thursday :data ((boop) (beep)))) |#
20:16:29
pjb
(getf (first (select :day 'thursday (select :week 1 '((:WEEK 1 :DAY MONDAY :DATA ((BEEP) (BOOP))) (:WEEK 1 :DAY THURSDAY :DATA ((BOOP) (BEEP))))))) :data) #| --> ((boop) (beep)) |#
20:20:16
pjb
you may also write: (getf (first (remove-if-not (lambda (plist) (and (equal 1 (getf plist :week)) (equal 'thursday (getf plist :day)))) '((:WEEK 1 :DAY MONDAY :DATA ((BEEP) (BOOP))) (:WEEK 1 :DAY THURSDAY :DATA ((BOOP) (BEEP)))))) :data) #| --> ((boop) (beep)) |#
20:21:36
hashfunc77a
earlier i came up with: (GETF (FIND NIL '((:WEEK 1 :DAY MONDAY :DATA ((BEEP) (BOOP))) (:WEEK 1 :DAY THURSDAY :DATA ((BOOP) (BEEP)))) :KEY (LAMBDA (X) (CONS (GETF X :WEEK) (GETF X :DAY))) :TEST (LAMBDA (X Y) (DECLARE (IGNORE X)) (AND (EQ (CAR Y) DAY) (EQ (CDR Y) WEEK)))) :DATA) , but it doesn't work when put into a function
20:22:58
pjb
with find, you could do this: (find '(1 thursday) data :key (lambda (entry) (list (getf entry :week) (getf entry :day))) :test (function equal))
20:23:34
pjb
(getf (find '(1 thursday) *data* :key (lambda (entry) (list (getf entry :week) (getf entry :day))) :test (function equal)) :data) #| --> ((boop) (beep)) |#
23:26:19
jmes
I would like to use the repl to interact with a running process but when I start said process it blocks the repl. How can I change the process so as not to block the repl?
23:30:50
jmes
basic example, I set a value (defparameter *value* 'hi) then run (loop do (sleep 2) (print *value*)), now as the loop is running I'd like to set *value* to something else
23:39:18
pjb
jmes: alternatively: (loop do (print *value*) (princ "> ") (finish-output) (print (eval (read)))) ; then you can enter (setf *value* 'boo) inside the loop.
23:40:29
jmes
pjb: thanks, for some reason I was thinking there would be some repl-specific way to do it but I wasn't thinking :P
0:09:04
pjb
jmes: there could be. For example, there is often a hook called to display the prompt. But I know of no REPL implementing asynchronous features, for when it's idle. I've got an example here, but it's still synchronous: https://github.com/informatimago/lisp/tree/master/small-cl-pgms/irclog-prompter
1:25:10
zacque
From CLHS "case keyform {normal-clause}* [otherwise-clause] => result*", is there a reason for writing "{normal-clause}*" instead of "normal-clause*"?
1:27:54
zacque
In the ANSI CL standard, its syntax is "case keyform {↓normal-clause}* [↓otherwise-clause] -> {result}*"
1:29:33
zacque
Hmmm, my hypotheses is that {non-terminal} will introduce a list form? But that doesn't explain the syntax for "{result}*", which I think is to indicate that there may be multiple values returned
1:34:48
zacque
So, I find the use of "{}" to be inconsistent for a non-terminal group of one element only. And I'm asking whether it is indeed inconsistent or there is a special reason for such usage
1:57:40
Bike
don't quote me on this, but my impression is that the clhs uses {} for grouping, because () would be confusing since lisp itself uses it all the time
1:58:41
Bike
you can see down in otherwise-clause where it has "({otherwise | t} form*)", where the () are literal, and the {} are not, and also don't indicate repetition (as in canonical EBNF) or the introduction of a list form
1:59:23
Bike
the use of "=> result*" and such is common, and a bit confusing since when you're talking about return values you're no longer dealing with syntax at all
2:00:05
Bike
the BNF syntax is described in more detail in 1.4.1.2, but it doesn't actually define what {} mean that i can tell
2:47:56
zacque
Bike: Thanks, I'm well aware of the section "1.4.1.2 Modified BNF Syntax", but it doesn't explain the BNF syntax that it uses. E.g. [] for optional, and {} for grouping.
2:49:09
zacque
Ah, that's not "{?normal-clause}*", it's the down-arrow unicode symbol used in the standard. See: https://irclog.tymoon.eu/libera/%23commonlisp?around=1652146074#1652146074
2:51:34
Bike
oops, sorry. i haven't yet worked out how to get my terminal emulator to display unicode correctly.
2:53:10
zacque
> "{normal-clause}*" and "normal-clause*" mean the same thing <= Ya, that's what I assume to be true right now
2:56:04
zacque
> the use of "=> result*" and such is common, and a bit confusing since ... <= I don't find it confusing, instead very helpful in understanding the form of the result return
3:05:22
beach
razetime: An application is typically distributed with an ASDF system definition used to build it.
3:06:53
White_Flame
lisp is an interactive systems. various things you load into the image have their own entry points you call
3:07:32
beach
razetime: An application will typically create one or more packages as part of the build process.
3:08:43
zacque
razetime: "A large runnable application" is simply a function. E.g. a sophicated compiler can be exposed as the `COMPILE` function
3:13:10
White_Flame
oh, you mean just do your read-eval straight into april instead of the lisp form
3:14:03
White_Flame
(but I'm not an expert on what other nuances it might need, so season to taste :) )
3:16:36
zacque
You may start with a script, then organise your application into a system as it grows
3:38:51
contrapunctus
I'm trying to write a CRDT library and am having trouble with how to structure it in terms of CLOS. There are different CRDTs, e.g. registers, sequences, maps. Operations for each depend on the type, as well as the implementation strategy for the instance (state-based vs op-based), and also handling of concurrent operations (several ways for each CRDT, depending on the type).
3:41:34
contrapunctus
I tried defining implementation type and concurrency handling as slots whose values are keywords + using EQL specializers, but that makes method calls ungainly...
3:49:48
contrapunctus
I thought of defining a `crdt:abstract-register` class which is subclassed by a `cmrdt:register` / `cvrdt:register` (state-based vs op-based) ...but that still leaves the matter of how to specify and dispatch on concurrency semantics.
4:07:45
contrapunctus
I could follow that up with different classes for each concurrency behaviour - so `crdt:abstract-register` is subclassed by `cmrdt:register` / `cvrdt:register` is subclassed by `multi-value-register` , `last-writer-wins-register` (for both packages, `cmrdt` and `cvrdt` !!) ...but that would lead to a large-ish number of classes.
4:29:36
beach
contrapunctus: Maybe this is not relevant, but we (in the SICL project) have started writing libraries that take a CLIENT parameter. In our case, the library itself does not specialize to this parameter, but client code supplies a standard object, and can write methods on specified generic functions that do specialize to it. Maybe concurrency semantics could be done with such a CLIENT parameter?
4:30:55
beach
This idea works well if there is a lot of common and default code, but the "leaf" routines are likely to require some adaptation by client code.
4:35:43
beach
Sure. You can look at Eclector as an example. The documentation is quite good (and not created from docstrings).
5:26:09
zacque
Just found out that there is a "it" variable in the LOOP grammar, does anyone have an example of how to make use of it?
5:27:24
contrapunctus
zacque: I think it's for using the result of the predicate for either WHILE or WHEN/UNLESS
5:34:48
zacque
Code: (loop for x below 20 when x collect it) and (loop repeat 20 unless nil collect it)
5:34:57
beach
zacque: It is the same use as in anaphoric macros. I never use it, because if you follow the rules of page 13 of the LUV slides, it will always be T or NIL.
5:38:45
beach
zacque: For this case, it basically says that it is expected that WHEN and UNLESS be given pure Boolean values.
5:40:46
beach
zacque: If all semantically valid phrases were idiomatic, then we would have a total mess in most Common Lisp programs.
5:41:41
beach
The set of idiomatic phrases in any language (natural or programming) is a tiny subset of the grammatical phrases.
5:44:17
beach
The LOOP macro was probably not designed by the same people who suggested the rule in question. Just like Graham when he wrote about anaphoric macros.
6:21:03
zacque
Question: Where can the "function-name ::= {symbol | (setf symbol)}" be used in the DEFCLASS syntax?
6:44:01
zacque
Nvm, I got confused, I'd expect its syntax to be "function-name ::= reader-function-name | writer-function-name", where "reader-function-name ::= symbol" and "writer-function-name ::= (setf symbol)"
7:05:41
contrapunctus
beach: is this the same as FCGE? https://github.com/alex-gutev/cl-environments
7:14:38
jackdaniel
while luv slides are very insightful and are a good start for writing clean code, I think that the language "idioms" evolved slightly from the time these slides were written
7:15:15
jackdaniel
i.e Norvig is known for an excellent writing style, but if you read paip you'll notice plenty of places where lists and structures are used (instead of, i.e, standard classes)