freenode/#lisp - IRC Chatlog
Search
15:40:58
Shinmera
I'm also happy to announce that another Lisp website is finished: http://studio.tymoon.eu/ https://github.com/Shirakumo/studio
16:05:55
pjb
drmeister: I'd suggest a network dump, to check if the message is transmitted (is it lost before sending or after receiving?)
16:08:19
drmeister
I have a tiny example now of a python program that sends a request and waits for a response and a common lisp script that waits for a request and sends a response. The common lisp script sends the response but the python script doesn't receive it.
16:09:59
drmeister
The common lisp script works in cando - I'm currently trying to get it to work in sbcl.
16:21:05
drmeister
That contains the stuff that I'm sending. What is the localhost.54007 ? Is that the python code sending this out on another port?
16:21:52
drmeister
Here is the output of the Common Lisp script ( I can post the script as well - but it is longish)
16:39:15
pjb
If you don't seen any other packet, then it means the problem is on the sending lisp side.
17:06:48
drmeister
I suspect the problem is the identities part - because I had to add code to deal with the non-string nature of zmq's default identities.
17:14:18
trittweiler
drmeister: if you can't see any outgoing packet from 127.0.0.1:9734, then dive into pzmq:send. Does that have any kind of meaningful return value? Maybe the data is waiting in a buffer, and needs to be flushed out
17:15:48
drmeister
The main detail to notice when reading the man page is the requirement for adding in a null (empty) message part between the identity routing information prepended to all messages and the message body containing the application-level data. This null message part is used as a delimiter to separate routing information from application-level data. When communicating to/from REQ/REP sockets, the routing information is silently
17:15:48
drmeister
processed by the framework up to the null message part; the framework then hands off the remaining message parts to your application for processing.
17:17:12
trittweiler
presumably, the python side is doing that automatically? If that's the case you can inspect the request to get an idea how null/empty is supposed to look at the wire
17:19:04
drmeister
The python side isn't doing that - because I don't send an identity - my understanding is that the Python side will create an identity of the form #(0 w x y z) where w x y z are octets that code for a 4-byte random value integer.
17:19:37
drmeister
I'm trying different combinations of null in the python and null in the Common Lisp.
17:21:03
drmeister
No combination of b'' in the python and "" in the common lisp appear to change the behavior.
17:30:09
Colleen
Function emptyp https://common-lisp.net/project/alexandria/draft/alexandria.html#index-emptyp-137
18:37:52
shka_
i think that's because arch put it into /usr/include/hwloc/cuda.h instead of /usr/include/cuda.h
22:23:50
cgay
My CL is very rusty... Is there a standard way to break very long string constants across multiple lines? Do I need to use concatenate, or (format nil "firstline~\nsecondline") ?
22:28:47
cgay
format seems a bit better because it removes leading whitespace on continuation lines.
22:29:44
pjb
You could put a reader macro on #\" such as """ starts a string that can include newlines and indents that don't belong to the string.
22:37:01
phoe
the human reader will be able to infer that it's a constant if he sees #.(format nil ...) anywhere in the code
22:39:29
cgay
this string is used in one place (a command-line flag help string). i wouldn't want a separate constant for it. ideally there would be real string syntax for this, but oh well.
22:39:51
pjb
cgay: you can implement your ideal real string syntax. Reader macros are made for that!
22:43:17
cgay
It sounds like a lint rule that certain organizations could turn on if they wanted to.
22:43:56
pjb
(defconstant +foo+ (vector 1 2)) (setf (aref +foo+ 0) 3) +foo+ #| --> #(3 2) |# is perfectly conforming.
22:44:12
pjb
What is constant, is the binding between the symbol +foo+ and the pointer to the mutable vector.
23:28:15
aeth
Would be nice to have immutability in CL. You can kind of fake that without optimizations with :read-only slots in structs assuming implementations respect that (idk if it's required), although it's only really easy to fake conses with structs
23:29:20
aeth
idk if extending sequences for types/immutability or extensible sequences (and put this in a library) would be easier to get implementations to support
23:30:44
aeth
Is directly accessing slots even portable on structs? That's probably good enough for having read-only
23:31:59
aeth
hmm, okay, so you at least can get immutable conses that way, assuming you can come up with a cons-as-struct representation that doesn't rely on writers (mine does)
23:37:35
aeth
If I had to redesign CL I'd add optional immutability to conses and arrays (and hash-tables?) and :element-types for cars/cdrs (separately because you might want the cdrs to be (or null your-typed-cons) in the case of a linked list) and hash-table keys/values (again, separately)
23:37:48
aeth
I'd write a CDR for that but so few people respect CDRs that I think the site has been down for years at this point
23:39:22
gendl
And i'm running with Java 9 on my Mac. The ABCL docs say it only works through Java 1.8. Is it not supposed to work with Java 9?
23:39:30
aeth
Afaik current typed conses are O(n) since no type information is stored in the cons itself, so verification is done over the whole list. Instead of being able to say :car-type integer :cdr-type (or null cons-of-integers) and just getting a linked list that can only hold integers. Then you'd be able to verify instantly
23:43:23
aeth
Yes, ideally arbitrarily many. I hate how :element-type in arrays has to be something like (unsigned-byte 8) or fixnum and can't just be (integer 0 42) separate of what's internally used to store them.
23:43:54
PuercoPop
aeth: yes, not having strings immutable by default is one of the criticisms Henry Baker makes to CL. Having them immutable by default would allow copy by reference in threads for example.
23:44:13
aeth
At the moment, type information is lost in data structures except for (maybe) :type in struct slots and (unportable except for bit and character/simple-character) specialized arrays
23:44:57
Bike
with arrays it wouldn't be quite as bad since using an extra word for the type isn't unexpected, but could still cause difficulties.
23:45:45
aeth
PuercoPop: The two flaws I see in CL data structures are the lack of immutability and the loss of most type information
23:46:01
aeth
The more type information the data structures themselves remember, the less you have to use THE, DECLARE, etc.
23:46:54
aeth
Bike: The compiler knows 42 is an integer, a fixnum, an (integer 42 42), etc. until it's stored into a data structure
23:47:55
Bike
you're talking about a RUNTIME tag. the compiler STILL wouldn't know if there were typed conses. the runtime could know that a slot is supposed to hold whatever type, but that would improve correctness, not efficiency.
23:49:06
aeth
Bike: for numbers and sequences it improves efficiency because of type-generic functions like + and MAP. If it knows it's an (integer 42 42) then it will use efficient arithmetic for most +, -, /, *, etc. because it will (probably) stay a fixnum. If it knows foo is a list, it uses a more efficient LENGTH/MAP, etc.
23:50:56
aeth
SBCL doesn't check at runtime in (+ 3 (aref foo 42)) if it's arefing an (unsigned-byte 8) array that it knows the type of (it might do a bounds check if it doesn't know the full type, including the length)
23:51:07
Bike
if the hash-table doesn't have a compile time known element type, it's just as efficient either way: right now, the runtime checks whether the gethash result is a fixnum. in your version, the runtime checks the stored element type in the gethash, and dispatches with arithmetic based on that.
23:51:43
Bike
with completely arbitrary runtime element types it could be less efficient, since it has to compute subtypep or something.
23:51:46
aeth
(defun foo (a) (declare ((simple-array (unsigned-byte 8) (43)) a)) (+ 3 (aref a 42))) ; efficient +
23:52:14
Bike
that's a compile time declaration. that is a separate concern from run time type information.
23:52:51
aeth
If a have a linked list that can only store foos, I can trust the user's input to only have foos because the compiler or runtime will error before that list is given to me.
23:54:23
aeth
It wouldn't be more efficient in general, but there are cases where it would be more efficient, like iterating over an array whose bounds are carefully set so that the arithmetic is efficient. It checks the array's type once and the compiled arithmetic can be efficient.
23:55:49
aeth
This exists in a limited extent already, e.g. an array of 1,000,000 (unsigned-byte 8)s will have efficient (dotimes (i (expt 10 6)) (format t "~S~%" (1+ (aref foo i))))
23:56:35
Bike
it probably wouldn't be more efficient now, as it would require complicated coordination between aref and 1+.
23:57:35
aeth
But the main reason you'd want immutable and holds-only-certain-type things would be for correctness, yes.
23:59:31
aeth
(It wouldn't always be more efficient, you could probably encode stuff in a SATISFIES type in a way that's bad)
0:00:31
Bike
what you're talking about is basically moving correctness checks up to when they're constructed or written to. (defstruct kons (type t) car cdr) (defun (setf kar) (v kons) (assert (typep v (kons-type kons))) (setf (kons-car kons) v)) etc
0:03:41
aeth
Bike: Well at the moment I do something similar except it's closer to (defstruct kons () (car nil :type foo) (cdr nil :type (or null kons)))
0:03:46
Bike
then you could hypothetically have a reduce definition that does (cond ... ((and (eq function #'+) (typep sequence 'kons) (subtypep (kons-type sequence) 'fixnum)) (setq function #'fixnum-+)) ...))) bla bla bla.
0:06:35
aeth
You could have a foo-cons that can only hold foo in the car and (or null foo-cons) in the cdr, not suitable for arbitrary uses of conses, but suitable for typed singly linked lists
0:07:54
aeth
Right, because it's arbitrary there would have to be some generic name, such as (typed-car my-foo-cons) or (car* my-foo-cons) and so you'd need to inform the compiler that you know it's a foo-car. Perhaps with THE or DECLARE or CHECK-TYPE or maybe just because you created the foo-cons somewhere earlier in the function
0:08:25
aeth
Otherwise you'd lose the efficiency, but you'd still be able to say some things as far as correctness goes
0:09:03
aeth
Bike: Yeah, basically some form of static-generic data structure like you'd see in the static languages
0:09:52
aeth
But that way you could just do (check-type something 'my-foo-cons) and then the compiler will know for the rest of the function that the cars of something have to be foo
0:09:59
Bike
as you're probably aware, you can declare the types of the car and cdr of a cons now. you'd just need a relatively small extension to declare proper list types.
0:11:24
aeth
That's what you'd need to only have to verify the head. At the moment, I do that in structs
0:11:38
aeth
Would be nice to be able to use all the list operations and get all the type information
0:12:15
aeth
Bike: What kind of extension would hash-tables need? e.g. key-type KEYWORD and value-type (UNSIGNED-BYTE 8)
0:13:38
aeth
Having e.g. an ub8 value-type seems like it could be allocated efficiently at the back end, too
0:14:53
Bike
there's no great reason to know that you declared an array to have element-type (integer 17 2083) at runtime, fixnum is fine for that, but the compiler might want to know that about an array.
0:16:41
aeth
I disagree. (integer 17 2083) might be an important precondition for your function to work as expected, and you lose that precondition because e.g. on SBCL (upgraded-array-element-type '(integer 17 2083)) => (UNSIGNED-BYTE 15)
0:17:26
Bike
it might be good for correctness. but it would be substantially slower correctness. and you can always do that precondition yourself.
0:19:41
aeth
It would check on write, assume on read (as long as it knows what the precondition is before AREF time), so there are situations where it could be faster. e.g. If you're subtracting 17 from the AREF, the compiler will know it stays unsigned
0:20:45
Bike
you can, right now, declare that an array has element type [whatever integer thing] and the compiler can take advantage of that if it wants. that's not the new part.
0:22:38
Bike
and types-as-predicates, that was the fourth i identified when i thought about this too much
0:24:49
aeth
Well, at the moment types in CL are usually used either for correctness or for performance (sometimes both)
0:26:55
stylewarning
I don't load up a bunch of CHECK-TYPES because I want things to error, but just because I want to remember what I'm supposed to pass to a function (:
0:26:56
aeth
stylewarning: I would file that under correctness because you're assuming the user doesn't read the documentation :-)
0:28:50
stylewarning
i've been writing up a document about a tentative plan to implement a dialect of ML in Lisp because I want some clearer value coming from types
0:30:34
aeth
I've been writing a lot of my CL functions as essentially statically typed with type declarations. The type declarations are checked in SBCL and CCL and they're used for static typing in (at least) SBCL and for various reasons pretty much every other implementation doesn't run my code other than SBCL or CCL so I can rely on the type declaration behavior.
0:31:22
aeth
The problem with check-type is that SBCL correctly infers that the function arguments are of type T because the CHECK-TYPE will be happy to replace them with the correct types at runtime.
0:32:23
aeth
In theory my macro that generates functions with type declarations in a slightly more convenient syntax can also generate check-types in other implementations just by pushing that to *features* and having a #+foo change the default behavior of define-function on those implementations
0:33:07
stylewarning
aeth: WITH-EXPECTATIONS: https://bitbucket.org/tarballs_are_good/policy-cond/src/568186761e1965dda952c129e3e92264c59389fe/README.txt?at=default&fileviewer=file-view-default
0:33:26
Bike
to elaborate on the compile/runtime thing. when you're talking about (check-type array '(array [integer nonsense])) not iterating, that's information thatll have to be stored in the array somehow. that stored information cannot do shit for the compiler. a check-type or declaration could, but that's actually orthogonal to the runtime information.
0:36:20
aeth
the only problem is that it relies on type declarations. It can't tap into the type inference
0:37:49
stylewarning
ad hoc polymorphism is nice with types/classes/CLOS/spec-store/whatever, but I meant parametric polymorphism above, where we define a function that's singly generically useful for many types
0:39:25
Bike
you'd probably have to specify the set of types you want to polymorph over ahead of time, which is kinda bleh.
0:41:24
stylewarning
I mean, supposing some function F was polymorphic over a type variable S, then calls to F would need to check if it was specialized for S's instantiation, and if not, generate that code
0:43:12
stylewarning
I bet you could get something to work, but I don't think it's a good use of something like spec-store.
0:43:37
stylewarning
spec-store or my own worse version of it is good for when you---as you said---know types at compile time and want to specialize accordingly
0:44:27
Bike
the whole 'generate that code' bit implies a lot of crazy and yet extremely boring problems with compilation units. last time i asked C++ compiler people about it they went off to get blackout drunk
0:49:34
stylewarning
rambling about static types in lisp https://github.com/tarballs-are-good/coalton/blob/master/thoughts.md
0:53:57
aeth
I use static types (and similar things) a lot in my game engine. And there are drawbacks to static types, they just seem to make sense a lot in the core of a game engine.
0:54:21
aeth
on the other hand, in that same engine in functions called from defmacro everything's pretty dynamic
1:00:35
aeth
What I like about CL is that it's a messy mix of everything all in one language, so you just use whatever's most convenient for the problem.
1:01:52
stylewarning
aeth: I have often said something like that, but I think that viewpoint would benefit from more refinement.
1:05:20
aeth
Well, I think the downside with CL is that its weaknesses are things that have gained popularity since the mid-90s. Stuff you see in Haskell or Rust or Go, etc.
1:06:41
stylewarning
aeth: I think a "weakness" that is present in the current ecosystem is just lack of completeness, comprehensiveness, or robustness.
1:07:04
aeth
You even see stuff in Java that CL is lacking, like a rich standard library full of lots of built-ins like queues, sets (other than the very weak lists-as-sets), etc.
1:07:21
stylewarning
Maybe I want to write in a functional fashion. What are my options? Use a mishmash of Alexandria, FSet, and a few other things?
1:07:55
aeth
What you miss with custom data structures is (1) whatever the library author (or you) forgot to add and (2) any kind of convenient way to use them
1:08:40
stylewarning
I think 1 and 2 are really, really important. 1/2 are the reasons people use a library/paradigm/whatever.
1:09:26
stylewarning
"You can do functional programming in Lisp because it has all of the fundamental primitives you need." -- generally not convincing enough for me to employ a functional paradigm, because it's asking me to roll out and "complete" the paradigm
1:09:41
aeth
Pure FP in CL is almost as bad as pure FP in JavaScript, btw. You lose any kind of efficiency that you'd have in a language like Haskell.
1:10:20
stylewarning
Anyway, this is the point I'm making and what I meant about refining that viewpoint.
1:10:46
stylewarning
You can access a lot of "primitives" to lots of paradigms/ways of doing things, but they're often just not full featured or complete or 100% integrated
1:11:02
stylewarning
But that's almost never Lisp's fault, and it's almost never the compiler writers' faults.
1:11:19
aeth
CL's pretty much still #1 in dynamic OOP, although that's kind of out of style at this point
1:14:08
aeth
stylewarning: I'd go farther and say not only can you do lots, you can do pretty much anything in CL through elaborate enough macros (or reader macros), but it won't feel integrated and it probably will be via an undocumented, incomplete library
1:15:03
aeth
At a far extreme you could have a reader macro with a new syntax compile down to an implementation's inline-assembly or something.
1:19:03
aeth
at least at the state it's currently in, I'd personally say Lisp is more like a language for writing functional (or at least declarative) languages than a functional language
1:20:08
aeth
I'm actually surprised there aren't more languages like Shen that have a CL backend. (Although, personally, I'd *just* have a CL backend rather than have like 20 backends like Shen does)
1:23:47
asarch
Well, I am reading at Sonja E. Keene's book (Object-Oriented Programming with CLOS) that for each Common Lisp data type, there is an equivalence CLOS class for that
1:29:10
stylewarning
asarch: It sounds like you have a wrong model of what Lisp is like or what its syntax is. You'd benefit from reading PCL.
1:33:14
asarch
When I was learning to develop web applications with Perl with Catalyst, I found that Catalyst uses the new object system of Perl called Moose which is based on Class::MOP which it uses the Meta-Object Protocol