freenode/#lisp - IRC Chatlog
Search
12:56:13
pjb
For example, you could define a reader macro: Ɦ((:test equal :rehash-threshold 0.5) :hi 1 "Hi" 2)
12:59:05
beach
jmercouris: The Common Lisp HyperSpec says: The :reader 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.
12:59:25
pjb
Or you can use both :reader and :writer when the names are different, vs. a :accessor that use the same name for both.
13:01:05
pjb
(defclass account () ((solde :type integer :reader balance :writer in-the-bank))) (let ((a (make-instance 'account))) (in-the-bank 42 a) (balance a) ) #| --> 42 |#
13:02:12
pjb
Also, indeed, you can define methods behaving like readers, writers or accessors, without a slot.
13:02:20
jmercouris
I'm basically asking why does :reader exist, if :accessor exists, and I guess the answer is to make a slot-value read only?
13:02:37
pjb
(defmethod interest ((a account)) 0.0) (interest (make-instance 'account)) #| --> 0.0 |#
13:02:48
Bike
or to give the reader and writer different names, like for example if only one is exported
13:03:03
shka_
jmercouris: also, sometimes you want to have reader and writer, and export just a reader
13:03:31
jmercouris
so here's another thing though right, can't any client just redefine your class and add an accessor to get access to whatever you are hiding?
13:05:03
jmercouris
so far, I have been programming common lisp entirely without any sort of "enforced" encapsulation, but this might be a good idea for exposing interfaces to 3rd parties
13:06:45
jmercouris
so, let's say you have a slot that only has a reader, you can then only use slot-value to set its value, right?
13:06:57
jmercouris
so then, if you are saying, don't use slot-value, and you only have a reader, what should you do?
13:07:26
jmercouris
make a writer but not export its symbol outside of your package? is that basically your only course of action?
13:07:29
makomo
jmercouris: you define a writer (or both a reader and a writer by using :accessor) separately with a different name
13:07:32
beach
jmercouris: Wow, you have to distinguish between client code and code for your own module.
13:07:59
beach
jmercouris: Client code may only see the reader, whereas you can have a writer for your module implementation.
13:08:10
shka_
jmercouris: i for instance always name reader to be read-foo, writer write-foo and accessor access-foo
13:09:25
jmercouris
is it just a class that we only initialize and then that's it? we can never set it?
13:10:08
shka_
jmercouris: essentially, it is like saying that java class without public members can't be used
13:10:45
jmercouris
ok, it is making more sense to me now, and I now see why there is no writer here
13:10:47
beach
jmercouris: For example, if you create an instance of PERSON, you can put the date of birth in there. It won't ever change.
13:11:10
jmercouris
here is a case of enforced immutability in common-lisp, that's something quite new to me!
13:11:47
jmercouris
without a writer function, I imagine the author is strongly implying, don't write to this slot
13:12:02
makomo
jmercouris: it is not enforced, you can always use slot-value. the thing you were getting at with "enforced encapsulation" is an important point
13:12:23
makomo
jmercouris: it's just like python. you have access to everything, but you really don't want to access the implementation details of the class
13:12:35
jmercouris
I guess nothing in lisp is really ever enforced, we can always :: to get at a symbol anyway
13:13:04
beach
jmercouris: Luckily. Otherwise debuggers and inspectors would not be possible to write.
13:13:19
shka_
jmercouris: it is interactive, and it is hard to work (program, debug) in interactive envs if there are walls everywhere
13:13:46
makomo
jmercouris: "what if" in the sense, "what if my client changes this variable, oh no!"
13:15:00
jmercouris
beach: I remember you saying you don't like the usage of the word self within a defmethod, does it bother you that it appears in the hyperspec so?
13:15:24
jmercouris
I think you had said it bothered you because it was a remanant of single dispatch object oriented systems
13:17:10
jmercouris
I guess the problem is, if you are specializing on multiple classes, you can't just say "self" for all of them, so there will be this inconsistency
13:17:33
jmercouris
what if instead of self you write something like classa-instance classb-instance, would that appeal to you more?
13:19:37
jmercouris
I can't think of anything better, and I'm sure many people have spent already many hours thinking about it :D
13:21:30
jmercouris
phoe: yeah, I get that, that's what I was trying to say above, albeit, far more ambiguously
13:23:11
jmercouris
I wrote a project recently for a client, in Lisp, and the developer taking over the project was asking me, "why did you do it in lisp"? Felt kind of like an accusation, like I had burdened them in some way by picking this arcane language that they would now have to work on
13:23:57
jmercouris
I told them why I picked the language, why it was faster for me, but it felt like trying to win a holy war, in which I had comitted an atrocity, and had to atone or something, not sure how to explain it, but without them knowing the language, I couldn't articulate to them why I had chosen it
13:24:42
jmercouris
so, perhaps more appropriate for #lispcafe, but the question is, how do you explain your decision to those who question you in a way that they can understand, when they don't know the language
13:26:35
russellw
Be careful of assuming everything has to be about explanations and understanding. Most human interactions are more about social status. So the real point of an answer to something like that is replying in such a way to make it look like, you, your language and your community are at least as high status as his
13:28:42
jmercouris
interesting, so you are saying it is more of a "tribal war" type query than one of genuine interest in understanding?
13:29:20
phoe
russellw: "it works the best for me as a programmer and I can deliver the most value in this language"
13:30:07
jmercouris
that is more or less what I said, I couldn't think of what else I could tell them that would make sense without a lot of context and background
13:30:11
russellw
phoe, good start, but allows too much possibility that another language might be better for the majority of people
13:30:32
russellw
I would say something more like "best tool for the job" or "most powerful language anyone has yet come up with"
13:30:40
phoe
russellw: sure, that's actually true - Lisp isn't a good choice for a lot of programmers and they'll produce more value in other languages
13:31:06
jmercouris
I wanted to find some sort of appeal to authority where I could say "X is in Lisp" to demonstrate that it has been shown to be capable for application in the domain of the application that I wrote
13:31:29
russellw
But it's not just about the words, it's also about the tone. Your tone needs to suggest that your answer is really obvious formality, and not subject to debate
13:32:06
pjb
jmercouris: there's an important point here. In C or C++, since you can write random pointers, you can write randomly into any object very easily. But in lisp you cannot make random references, so it's impossible to write to an object unintentially.
13:32:09
phoe
russellw: I think that "works the best for me" is an obvious formality enough - you can't really debate with that
13:32:40
russellw
If you really have to bring first-person pronouns into it, at least say something like "I find it the best tool for this kind of project"
13:32:52
phoe
it's simply stupid to say "but you're more proficient in Java++, I know it for some reason" if you're a customer
13:33:27
russellw
phoe, I was talking about the presented scenario where the challenge did not come from the customer but from another programmer
13:33:40
pjb
And you still have the god-mode access to slots with slot-value, unless it's overriden for your class or your object ;-)
13:33:43
russellw
If it comes from the customer, then that is a different scenario. He who pays the piper calls the tune
13:34:17
jmercouris
I wonder how hard it would be to make a lisp --> java compiler that produces sensible looking code
13:34:22
russellw
So if the customer asks about your choice of language, say something like "I believe this is the best tool for this job, but it's your call"
13:34:23
phoe
as for the programmers, I'd say it's the bendiness of the language - allowing to tailor the language towards the problem instead of only having the option of hammering the problem into the language
13:35:13
russellw
jmercouris, as far as I know, no one has ever written an x->y compiler that produces readable code for any x,y
13:35:30
phoe
jmercouris: it'll be tough, since you'll need to reinvent a big amount of mechanisms. multiple inheritance, conditions, dynamic variables all don't exist in Java or even the JVM.
13:36:09
jmercouris
multiple inheritance could be circumvented through the use of protocols that multiple classes implement
13:37:56
phoe
the trouble begins when you start trying to compile actual features of CL as a language.
13:38:43
phoe
you suddenly get to embed chunks of the Lisp runtime in that language to be able to support them.
13:39:04
phoe
and be able to bend and modify the control flow in the language in case of conditions and CLOS dispatch.
13:40:05
phoe
which, at some point, stops being readable at all, unless you start abstracting things away.
13:41:47
jmercouris
I mean for example, in the example I mentioned above, imagine if my CL could have been compiled to python
13:42:18
phoe
if anything, embed a Python runtime in your Lisp image and use that python as a scripting language for your Lisp image.
13:42:44
jmercouris
it wasn't the customer, just the developer who is taking over the project for the customer, after my initial implementation
13:43:11
russellw
But you described a scenario where the customer was happy and it was a rival programmer who would've preferred Python. In that scenario, you need to get more confident and better at winning status fights
13:43:36
jmercouris
so they had been working on this project for like 6 months, and in Lisp I did it in literally one week
13:43:58
phoe
jmercouris: are you working in some kind of company? are you a freelancer? a consultant?
13:43:58
jmercouris
the customer was replacing me because I do not have the time to give them, there are other projects that demand my attention
13:44:09
russellw
Well of course the rival programmer was not convinced! You made him look like an idiot!
13:44:42
phoe
yep - tell them that this project is in Lisp and they'll need to learn it to be able to develop/maintain it, just like with any other project
13:44:59
jmercouris
I told them yes, I linked them to PCL, Portacle, and wrote some pretty thorough documentation
13:45:11
jmercouris
Josh_2: don't worry, you're not alone, it won't launch on most people's machine, unless they are on a Mac :D
13:45:57
jmercouris
Josh_2: Yes, I am sorry about that, we are working hard on the new GTK version using the Lisp Core -> Dumb GTK front-end architecture we previously discussed in this channel, so it should work for you, hopefully within a couple months
13:50:30
jmercouris
Josh_2: basically we have a program written in pure lisp that uses xml-rpc to control a client written in c/c++ gtk/qt
13:50:49
jmercouris
that client needs to respond to some basic commands like make-window, delete-window, make-buffer, set-visible-buffer-for-window, etc
13:51:35
jmercouris
this adds greater stability, significantly more consistent cross-platform performance and support, and a more reliable/reproducible build process
13:52:02
jmercouris
whatever technology GUI framework/web engine comes out in the future, it will be easy to port to because of this API that the LISP core and the GUI will use to communicate to each other with
13:53:41
jmercouris
thank you, it was not my idea, all credit to beach , it is however a huge pain to implement and very challenging :D
13:54:24
jmercouris
even just thinking about what is the minimal API needed to control the GUI application was an incredibly time consuming task
14:01:05
jmercouris
If there was a de-facto GUI framework / web engine port for Linux, it'd be an easier target
14:04:09
lukego
Suppose you have a static programming language with relatively weak abstraction capabilities. So you make an S-expression representation of its source code and then write programs using CL macros. Final step is to generate readable code in the target language with no dependency on Lisp. What's the best example of this approach?
14:12:03
lukego
Relatedly: Have many people taking this approach to hardware description languages like Verilog and VHDL? I googled for this and found Verilisp that seems like exactly what I was thinking of but with a mysterious status (homepage not even on internet archive.) I'm not sure if this is what Marc Battyani does.
14:12:28
ggole
It's convenient to make free use of let, and the compiler will have no trouble with redundant variables, but a human reader of the output might not be pleased.
14:13:03
Bike
HDLs have their own problems because they're not programming languages, and because you can't usually access the "assembly" level because of proprietary-ness
14:15:56
lukego
Verilisp looks awesome in the ECLM sense. Like somebody who wanted to build hardware just decided to use Lisp and bloody well did it. Code looks funky to a Lisper though :-) giving closing parens their own lines like C braces, defining functions like REMOVE-IF-NOT and EXPT with comments thinking they are not already built in..
14:20:18
lukego
also liberal use of EVAL in cases where the idiomatic Lisp is not obvious and author doesn't care but just wants to get shit working. Man, this is a pleasure to read :)
14:35:21
lukego
Reminds me of the time a guy turned up at ECLM talking about how he'd written a successful commercial product for designing aeroplane engines in Common Lisp, afaik with no prior experience, just a bright guy with a problem to solve who somehow recognized Lisp as a good fit
14:46:14
makomo
right, but i mean without catching the condition. i was thinking of something like COERCEP
14:49:26
makomo
i'm reading some data from the user. these objects should be something that is coercable to a certain numeric type stored in *type* (which can be changed at runtime by the user)
14:50:13
makomo
if it's not possible to coerce the values, i would like to report a proper error, instead of letting the following code just explode or w/e
14:56:04
lukego
Thanks again pjb. I'll make a deep dive on the LTD code. Just brilliant to have Norvig code for inspiration.
14:56:58
phoe
makomo: (handler-case (coerce a b) (error (e) (error (make-condition 'coerce-error :data a :type b))))
14:59:02
pjb
makomo: notice that implementations are free (and even must have to) implement additionnal coertions.
15:00:18
pjb
makomo: in the spec of coerce, notice the use of the expression: *recognizable* subtype.
15:00:40
pjb
recognizable subtype n. (of a type) a subtype of the type which can be *reliably* *detected* to be such by the *implementation*. See the function subtypep.
15:01:01
pjb
So COERCE is highly implementation dependent, at least when you use it on strange types.
15:01:59
pjb
For example, consider: (values (eval '(lambda (x) (list x x))) (compile nil '(lambda (x) (list x x))) (coerce '(lambda (x) (list x x)) 'function))
15:02:46
pjb
makomo: You may get the same result for the 3 values, but you could also expect to get an interpreted function from eval, a compiled function from compile, and whatever is best for the implementation, according to the implementation from coerce.
15:04:31
lukego
beach: I find myself in the pleasantly surprising situation that I want to prototype a little project and CL seems like the only suitable language :)
15:04:47
pjb
makomo: another example, I hear that sbcl has other sequence subtypes than vector and list…
18:24:12
jcowan
Lisp-flavored C is not uncommon, though it usually doesn't escape particular Lisp implementations.
18:30:09
kristof
(let ((x (the single-float 0.1)) (y (the single-float 0.2))) (the single-float (+ x y))) => 0.3
18:34:35
jcowan
it so happens that when you add the nearest approximation to 1/10 to the nearest approximation to 2/10', you get the nearest approximation to 3/10.
18:34:50
jcowan
(this is in double-floats, I don't have single-float support handy with a printer I trust)
18:38:09
kristof
D also does this. I presume it has something to do with the way floating points are printed from their binary representation and I know there's some tradeoffs to be made there
18:38:13
aeth
SBCL does something special with floats. Even double-floats. I wrote something that ran in SBCL, CCL, ECL, and CLISP... and for one of the five values, the error was really huge in all of them except for SBCL.
18:38:46
kristof
I wonder if this is the first time someone came in to this channel to complain of correctness and utility
18:41:13
aeth
Well, (defun foo () (let ((x (the single-float 0.1)) (y (the single-float 0.2))) (the single-float (+ x y)))) is compiled to constantly return 0.3 so I'd test with (defun foo (x y) (declare (single-float x y)) (+ x y)) (foo 0.1 0.2)
18:48:51
jcowan
aeth: 0.30000000000000004 and 0.3 are two tokens for the same double-float, but the former is in some sense the canonical one.
18:55:57
kristof
anamorphic: (loop for (sym val . rest) on '(a 1 b 2 c 3 d 4) by #'cddr do (print sym))
18:56:12
jcowan
Scheme requires it, and AFAIK the last holdout against doing so has now given in. There is no C requirement to do so, but at least glibc always prints the shortest correct representation. CL doesn't have a requirement either, but I'd be surprised if any CL implementation does otherwise.
18:56:22
kristof
however that will give you the final nil so you should throw a when clause in there
19:02:06
kristof
I was confusing the return value of the loop function for the print action. The first thing I wrote works just fine.
19:04:10
kristof
does slime support a way to do newlines at the prompt? Sometimes I don't want to load forms from a scratch buffer, I just want to write in the single buffer.
19:15:51
phoe
it does support them as long as you do not have a complete form; for example, "(+ 2 2)" and RET triggers evaluation but "(+ 2 2" and RET creates a newline.
19:16:19
phoe
I frequently delete the last closing parenthesis after typing the opening one creates a pair, if I expect to be writing a multiline form.
19:17:03
kristof
SBCL's repl does but slime does not... on Atom, at least. Does it have that before on emacs?
19:32:36
LdBeth
For slime the editor processes the form rather than the Lisp itself, it doesn’t know very well on when to send it, sometimes it even applies to GNU/Emacs
20:14:05
aeth
In SBCL, SLIME's #'sin is (FUNCTION (T) (VALUES NUMBER &OPTIONAL)) and (introspect-environment:function-type 'sin) is (FUNCTION (NUMBER) (VALUES (OR (SINGLE-FLOAT -1.0 1.0) (DOUBLE-FLOAT -1.0d0 1.0d0) (COMPLEX SINGLE-FLOAT) (COMPLEX DOUBLE-FLOAT)) &OPTIONAL))
20:14:56
aeth
(And it's not for portability, I don't think either even has function types in the other implementations)
20:18:27
Bike
"slime's" is the derived type, whereas the one you attributed to introspect environment is the declared type
20:22:51
aeth
In SBCL (and I think just in SBCL) it has the line TYPE: (FUNCTION (T) (VALUES NUMBER &OPTIONAL))
20:23:38
aeth
But personally if I was for some reason debugging something involving #<FUNCTION SIN> (obviously this is just an example) then I'd find the declared type to be more useful.
20:24:14
aeth
Well, I (setf *print-case* :downcase) most of the time, but I keep having to restart SLIME to switch implementations/etc.
20:24:36
Bike
as you can see from looking at the source, slime-inspect on sbcl for functions uses the simple-fun-type that's actually in the function object, rather than the declared type
20:26:56
aeth
Well, this is weird. (sb-disassem:disassemble-code-component #'sin) shows the very small entry point of a T input value. I declare stuff all the time and there's usually a check in the part that's in sb-disassem:disassemble-code-component but not in cl:disassemble
20:35:49
aeth
Actually, what I think is going on is that SBCL's declaim ftype and SBCL's type declarations are separate things, but when you declaim ftype for something you write you also type declare or something. (declaim (ftype (function (number) number) bar)) (defun bar (number) (sin number)) will produce a #'bar as if I did a (declare (number number)) even though I didn't.
22:00:46
skidd0
or, how can i directly manipulate the lack.response reesponse structure before sending?
22:15:28
jcowan
Well then, why bother to have external symbols at all and require a (slightly) more verbose syntax to access them from other packages? (This is not a rhetorical question.)
22:34:02
skidd0
to get access to the lack.response, would I want to do something :around the CALL method?
22:56:39
Bike
skidd0: it doesn't replace, but if your :around method doesn't call-next-method the original method will not be called
23:56:10
skidd0
I'm getting an error where hunchentoot doesn't know how to handle options http requests