freenode/lisp - IRC Chatlog
Search
8:02:05
npfaro
((:TRANSLATIONS ((:TRANSLATION . "Do you think that's a good thing to do?"))) (:WORD--COUNT . 7) (:CHARACTER--COUNT . 17))
8:07:38
npfaro
i can't seem to find a predicate for it, so should i just make a substring and check that
8:13:20
beach
npfaro: Perhaps it is unorthodox because most languages don't allow keyword arguments to modify the behavior, and they don't allow "out of band" return values.
8:14:10
beach
npfaro: Lots of things about Common Lisp are that way, luckily. CLOS, the condition system, macros, keyword arguments, multiple values, etc.
8:18:02
npfaro
The only issue is that mismatch returns nil when the arguments are equal, so (zerop (mismatch ...)) breaks when they're equal
8:18:09
beach
It's a bit sad, though, that the intrinsic limitations of other languages would make them "orthodox".
8:21:26
loke[m]
Can't you do something like (NOT (MISMATCH s1 s2 :end1 #1=(min (length s2) (length s2)) #1#))
8:22:33
Nilby
In my own far off world that matters little, I say begins-with and ends-with, because I find the mismatch and search forms unintuitive.
8:25:03
loke[m]
beach actually I meant NOT, because the CLHS specifically says that MISMATCH returns “false”
8:26:09
beach
Note to self: In WSCL, consider specifying that MISMATCH returns NIL as a default value.
8:26:35
loke[m]
I think it makes sense. MISMATCH is a predicate function that also happens to return a useful value when returning true. :-)
8:27:57
loke[m]
Speaking of nil, I saw someone complaining about the terms NULL and NIL. He suggested a compromise: NILL
8:32:27
beach
It may have been the case that you could fit 6 characters in a 36-bit word at some point.
9:52:09
pve
Hi, I'm thinking about how to organize the compilation order of my program. Is there an easy way to tell ASDF to load a file A from source (to get some basic functionality) then compile and load some other files to extend the functionality and finally compile and reload file A to ensure that the fasl is built with the full functionality?
9:56:50
arora
I am new to lisp, my university professor suggested to learn it for AI course, what's a good way to start?
9:59:38
beach
arora: Most AI today is based on "deep learning", but for traditional AI, Common Lisp is both faster and more expressive than Python.
10:00:30
minion
arora: PAIP: Paradigms of Artificial Intelligence Programming. More about Common Lisp than Artificial Intelligence. Now freely available at https://github.com/norvig/paip-lisp
10:02:18
minion
arora: look at PCL: pcl-book: "Practical Common Lisp", an introduction to Common Lisp by Peter Seibel, available at http://www.gigamonkeys.com/book/ and in dead-tree form from Apress (as of 11 April 2005).
10:02:57
arora
Python has libraries like sklearn and numpy which makes AI easier, what does lisp have as equivalent?
10:03:46
beach
arora: I don't know what those libraries do, but some others here might. Not many people here use Common Lisp for AI-like stuff.
10:06:22
arora
beach: Yea that's what I thought too, I hadn't heard of Lisp being used for AI before
10:06:54
TMA
arora: From what I understand, those libraries are just python wrappers over some C and Fortran libraries. The wrappers are necessary, because python by itself is too slow for any kind of numerical computation.
10:06:56
moon-child
lisp was traditionally used quite a lot for ai. The creator of lisp was also the coiner of the term 'ai'
10:08:18
arora
TMA: but since a lot of people use them in python, it became the "standard" of doing AI
10:11:49
TMA
arora: This is less necessary with Common Lisp compilers that produce fast native code. However, the utility of libraries goes beyond any speedup, they reduce the amount of work a programmer is required to perform. There are Common Lisp libraries for numerical computations, for GPU interfacing, and others that can help you.
10:13:00
edgar-rft
AI in the 1970s meant "Artificial Intelligence", AI in 2021 means "Anal Intercourse"
10:13:17
TMA
arora: It used to be so that Latin was the language of science. Fashion changes. Python is now considered fashionable whereas lisp is thought of as démodé.
10:14:57
arora
I had people in my class talk bad about lisp because it does like a prefix notation of computation, like 5 + 2 = + 5 2
10:16:48
arora
since its quite different from the other languages, I dont see how its useful either, why does lisp have a different notation?
10:17:00
edgar-rft
Lisp indeed helped me to understand math better because I do not need to learn stupid precedence rules.
10:17:23
beach
arora: The term is "homoiconicity" and it lets the programmer manipulate programs as data more easily than other notation.
10:18:36
beach
arora: But Common Lisp macros represent a powerful extension mechanism that is made easy with homoiconicity. Other language users have to wait for the updated standard for similar extensions.
10:22:09
logand
common lisp macros are great, but should be used sparingly. it is much easier to use a function at compile time by wrapping it in macro as opposed to using macro at runtime by wrapping it in funcall+compile+backquote+lambda
10:22:34
beach
Yes, but that's not how it is used very often. Instead, it is used in macros, so that the macro function (which is just code) can generate new code from some input code.
10:23:50
beach
arora: In Common Lisp, the same language (i.e. Common Lisp) is used to manipulate code as the one used to manipulate other data.
10:26:12
beach
arora: I don't think it is possible to understand the power of Common Lisp by comparing it the knowledge of the existing languages you know. You need to learn it to "get" it.
10:27:51
beach
arora: #lisp is more for people who use it in some non-trivial way, or people who write compilers and other language tools.
10:29:38
beach
arora: In case you wonder, there is no such thing as a compiler or interpreted programming language. Those are properties of the implementation. Most Common Lisp systems compile on the fly.
10:30:11
beach
arora: That is why a typical Common Lisp implementation is 50 times faster than Python.
10:32:25
arora
Most of my friends are learning languages to get a job and make money and since lisp is unheard of, it is hard to find people who use that.
10:33:26
beach
If that's your goal, then sure, learn something else. On the other hand, if you like to know sophisticated programming techniques to become more productive, then Common Lisp is a good start.
10:33:49
edgar-rft
arora: I already made money with Lisp, for just the simple reason that nobody wanted to do it than me (no joke).
10:36:21
beach
arora: I think you will find that Common Lisp programmers (many of which hang out here) are on the average more knowledgeable than programmers of other languages, so if you like to hang out with smart people, Common Lisp is good.
10:36:22
beach
I think the reason for that is in fact that Common Lisp is a bit tough in the beginning. So only more knowledgeable people are willing to attack it. Just guessing of course.
10:37:03
edgar-rft
arora: you don't jet Lisp programming job offers every week, but it's wrong that you can make *no* money with Lisp.
10:37:44
beach
arora: But it won't be "peaceful". You will soon find that you will want to learn more and more.
10:38:37
beach
... so it becomes a lifelong learning experience. Which I personally love, but it's not for everyone.
10:38:42
arora
I don't mind learning more, infact that's all I like. What I do mind is being annoyed for making wrong choices.
10:39:28
beach
Not many people I know who learned Common Lisp decided later that it was the wrong thing to do.
12:08:47
VincentVega
hmm ok. I guess just returning a string between other forms could generate a warning as an unused expression, right?
12:11:11
VincentVega
although maybe it wouldn't, like it wouldn't for an empty progn, it's a macroexpansion after all
12:12:07
VincentVega
just insert a reminder inside a macroexpansion for those who may be inspecting it
12:18:10
VincentVega
thing is, you are sometimes inspecting the macroexpansion itself, to check that it's correct, or just reading it etc, you wouldn't necessarily be interested in looking at the macroexpander itself
12:20:17
phoe
I mean, you could create some objects that are then printed readably as #| ... |# but that would be sorta hacky I guess
12:21:25
phoe
if anything, I'd structure the macroexpander in a way that is easy to understand and test, or structure the macroexpansion in a way that conveys the necessary information through the expansion form itself
12:21:58
phoe
like (define-foo ...) that expands into (progn (define-foo-bar ...) (define-foo-baz ...) (define-foo-quux ...)) for something that defines multiple things at once
12:24:13
VincentVega
I am doing something like that. Just wanted to put a reminder not to forget to eval, well, based on your example, form (define-foo-bar ...) before expanding (define-foo-baz ...) (define-foo-quux ...) cause that's a prerequisite. As I said, not a big deal, asking more out of curiosity.
12:25:01
phoe
and your DEFINE-FOO-BAZ can signal an error if the matching DEFINE-FOO-BAR was not evaluated before
12:26:38
phoe
I should be able to macrostep into DEFINE-FOO and then DEFINE-FOO-BAZ without evaluating DEFINE-FOO-BAR first
12:28:38
phoe
because, unless you use some EVAL-WHEN trickery, this is exactly how the Lisp compiler is going to perform minimal compilation on your code
12:28:58
VincentVega
sly-macroexpand-1 your macro call, you will get a progn with 2 macros within. Say, the first macro defines a class. Then sly-macroexpand-1 the second macro which relies on that class and it will either signal an error because the class is undefined or it will be using the old definition of a class if it has been defined before, which is more
12:29:59
VincentVega
If your macro is building the class definition, it may be easy to forget that you need to evaluate it before verifying what the second macro is generating
12:31:05
phoe
and when I see (EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE) ...) in a macroexpansion then I can usually infer that the compiler state is going to be modified at this point
12:31:43
phoe
and this includes defining classes in the compiler environment that will then be used inside subsequent macroexpanders
12:32:37
phoe
but then I'd also separate the two macros because defining a thing and then immediately using it to define some other thing kinda violates the SRP
12:32:59
phoe
I'd first explicitly DEFINE-FOO-BAR that expands into EVAL-WHEN and only then I'd DEFINE-FOO-BAZ that uses the FOO-BAR thing defined earlier
12:35:18
VincentVega
I mean if one thing always goes with the other, why sepearte? I guess it is all one and the same responsibility here: in my case I am generating methods based on the class.
12:37:18
phoe
is it only used there, in that single place? maybe then an instance would be enough instead of a whole class? I don't know your architecture so just firing questions blindly now
12:56:29
ralt
with #:foo people don't have to wonder if it's a symbol part of the keyword package or anything like that, it's pretty clear
12:56:54
phoe
using the #: notation also carries the information that you only care about the symbol name, not its package information
13:31:33
VincentVega
phoe: I'm back : ) So, I have a metaclass which you can use to define extra slot options. Say, you could specify `:ensure-valid-on-read t` which will generate a `setf :before` which calls a compute method if the value is invalid. Or, if you have slots which act as cache and rely on other slots, you can specify all that, and the cache will be
13:31:33
VincentVega
invalidated when those other slots are written to (may not make for the most efficient approach, but it does ensure that things stay valid).
13:42:00
VincentVega
When you throw inheritence into the mix, keeping track of things like that manually can become a headache, and having it all written out in this type of declarative approach just keeps it clean and easy to understand.
13:53:07
jmercouris
in otherw words, I don't want to have to write (list 0 #+renderer-gtk 1 #+renderer-gtk 2 3)
14:00:20
beach
jmercouris: Your questions here made me curious about your background and training in software and theory, and I am wondering whether your background is typical. Do you mind sharing?
14:01:03
jmercouris
I'm not sure whether my background is typical or not, as I have only experienced my own life, but I can share yes
14:01:24
jmercouris
I have a degree in computational information systems from IIT, basically it is about data analysis/engineering
14:02:21
jmercouris
in graduate school I studied entrepreneurship and digital networks, I further expanded my understanding of data by looking at raw real world data, doing a lot of normalization, ingestion, classification work
14:02:44
jmercouris
I pioneered using machine learning to analyze the flow of information across digital social networks with regards to information diffusion
14:03:46
jmercouris
so my backgrounds is primarily concerned with data processing, and less with algorithms, which is my guess as to why most CS find me oft uneducated :-D
14:04:42
beach
My hunch is that this is an unusual background for Common Lisp programmers. But it's just a guess.
14:05:33
scymtym
there is a special case in which a single reader conditional can guard multiple sub-forms of a form: (list 1 2 . #+sbcl(3 4))
14:08:23
scymtym
jackdaniel: i tried to step around that by using the (possibly undefined) term "sub-form"
14:09:21
scymtym
i consider this a situational trick anyway since it only works for conditionally appending subforms at the end
14:11:02
scymtym
jackdaniel: i understood jmercouris' question as being about the general case, that is guarding and splicing at any point
14:13:23
scymtym
jmercouris: ok. so the trick is probably not useful to you. but i thought it might be not that well-known and thus maybe worth sharing
14:14:30
Bike
if you're actually doing (list 0 1 2 3), you could make that `(0 #+renderer-gtk ,@'(1 2) 3), couldn't you? or is mixing unquoting and reader conditionals not kosher?
14:20:01
pfdietz
The useful case is where you're calling a function with keyword arguments that you may or may not want to include. You could do APPLY and build up a list of arguments, but with m-v-c you can conditionally put the args right on the stack. No consing needed.
14:21:16
Bike
i like the thing in alexandria where curry does (multiple-value-call fn (values-list arguments) (values-list more))
14:29:49
heisig
Nowadays I always name conversion functions X-from-Y. There is no ambiguity, and things line up nicely in the source code: (X-from-Y (Y-from-Z ...)).
14:32:00
jackdaniel
I remember in LiSP the author has a similar concern, whether x->y or x<-y is better, and he mentions this argument that (x<-y (y<-z …)) lines nicer then the alternative
14:34:00
_death
if you define a x<-z or x->z then it doesn't matter that much (look like a law of demeter thing to me)
14:35:37
jackdaniel
when I see i.e (x->z (y->x (q->y 42))) it is less obvious to me whether it returns z or x, because the order of symbols doesn't really match the type conversion order
14:35:50
heisig
I also try to almost always use full English words instead of glyphs. Otherwise you quickly drift off to something that resembles obfuscated C code.
14:37:25
phoe
https://github.com/sbcl/sbcl/blob/3c87c3f8b67ad1de275762568f4b8f9e562f5930/src/code/symbol.lisp#L534
14:37:25
_death
I cycled between a->b a-to-b and a-b.. but my argument is that if you have a-to-b and b-to-c, and you wish to make a c out of a, you should write a-to-c
16:08:31
jmercouris
I'm thinking about this guy on Reddit who talks about extending CL with this new 'standard'
16:08:48
jmercouris
https://www.reddit.com/r/Common_Lisp/comments/kylep5/starting_a_batteriesincluded_extended_standard/
16:09:48
jmercouris
if anything the only thing I can really condone is a authoritative list of packages for beginners: eg. use this for JSON, use this for threads, etc
16:10:34
beach
On the one hand, there are people like this, screaming that the Common Lisp standard is hopelessly inadequate.
16:10:56
beach
On the other hand, often the same people seem perfectly happy to use languages without a standard at all.
16:11:24
astronavt
CL has a huge amount of batteries included. the problem is that they dont always fit the kinds of flashlights that people are designing in 2021 :)
16:14:01
beach
Oh, this person hasn't use the condition system, but still has opinions about the standard. :)
16:14:02
jackdaniel
many were just using cltl2 for some years before most implementation implemented the "rest" from ansi
16:14:54
astronavt
jmercouris indeed, i wish people would spend their energy writing useful libraries that do useful things, instead of imagining new standards that dont accomplish anything other than navel gazing
16:15:06
jackdaniel
adoption of the new standard is often inhibited by dragging compilers (i.e msvc supports c99 only since a few years ago)
16:15:34
jackdaniel
so arguably a new cl standard would be a bad thing (worst case scenario would be the "perl scenario")
16:16:31
jmercouris
would you suggest a Common Lisp 2.0 standard that includes bordeaux thread spec?
16:17:05
jackdaniel
that's not my point - I'm saying that CL standard do miss some things, and vendors plug these holes
16:17:40
jackdaniel
that's the point of standards - they draw a line of what /must/ be present in a conforming implementaiton
16:18:17
jmercouris
IF less exhaustive, THEN, how do you explain its relative success? has nothing to do with the standard
16:19:14
phoe
probably something from the list at http://community.schemewiki.org/?scheme-faq-standards
16:20:31
beach
Oh, there is also this idea that many Common Lisp programmers have, that Common Lisp deserves to be more widely used, and they blame the standard for that. I think they have completely misunderstood why Common Lisp is not more widely used.
16:21:49
jackdaniel
the word dialect is a slang, mostly used with "lisp dialect" -- that means i.e that cl and scheme are different lisp dialects
16:22:21
jmercouris
writing SBCL specific code is non conforming to CL, and possible, it is therefore a new language
16:22:29
jackdaniel
person who is used to read code of one will immedietely recognize some common idioms
16:22:58
jackdaniel
introducing new operators to existing language does not make it a different language
16:23:18
beach
jmercouris: That's not a reasonable definition. If a C compiler is distributed with a library function, that doesn't mean it is a different dialect.
16:23:33
jackdaniel
consider that you add a function "foo" to your lisp image, does it make it a different language?
16:23:33
jmercouris
and then I come up with language U that includes operators Q R T W is that not a new language?
16:23:55
jackdaniel
every act of programming would spawn a new language, and such distinction is not very useful
16:25:03
jmercouris
precision is not a god to be obeyed unquestioningly, sometimes imprecision is valuable
16:25:46
jackdaniel
being precise at all cost if of course wrong, but being imprecise without a reason is worse
16:27:21
jackdaniel
if you specify, that function arguments are evaluated from left to right, and that function arguments are evaluated in /any/ order - that are different sematnics
16:27:48
jmercouris
since objective-c is C + objective-c is it fair to say that C is objective-c but objective-c is not C?
16:27:53
beach
jmercouris: That's not enough. There are in fact code snippets that are simultaneously valid programs in many languages.
16:29:15
jackdaniel
https://en.wikipedia.org/wiki/Semantics_(computer_science) may be a good introduction
16:29:58
jmercouris
"Semantics describes the processes a computer follows when executing a program in that specific language"
16:30:00
beach
jmercouris: For every valid form in the language, what it does (return values, side effects).
16:31:25
_death
jmercouris: C programs are also Objective C programs, because the latter is compatible with the former
16:31:57
phoe
is every C program guaranteed to behave the same under ObjC? then it sounds like ObjC is a superset of C
16:32:33
_death
jmercouris: Objective C purports to be a language that extends C.. SBCL does not purport to be a language
16:32:48
beach
jmercouris: For one thing, it defines some semantics that is undefined in the standard.
16:33:24
beach
jmercouris: Because, according to the Common Lisp standard, it is still allowed to be called Common Lisp.
16:33:24
jmercouris
SBCL is not only a program, it is a specification, defined by the program itself
16:34:21
beach
jmercouris: Had the Common Lisp standard said that no additional operators are allowed to be defined by an implementation, then it would not have been an implementation of the Common Lisp language.
16:35:00
jmercouris
beach: does the standard ever do that though? is it ever restrictive by addition rather than subtraction?
16:36:04
_death
jmercouris: it's true that when you, say, add a function to a set of functions you can think of it as extending a (maybe implicit) language.. in that case, someone who uses SBCL-specific constructs is indeed programming in the implicit SBCL language
16:36:09
phoe
jmercouris: a standard function that is defined to return exactly N values must return exactly N values
16:36:38
_death
jmercouris: and since SBCL implements Common Lisp, then you can think of it as a dialect of Common Lisp
16:38:10
phoe
I guess that from this point of view GCC also has its own flavor of C, given all of the GCC-specific extensions
16:38:24
phoe
and the fact they're required to build e.g. the Linux kernel, which is written in this C dialect
16:38:46
_death
jmercouris: but often, the useful view is that you're programming in Common Lisp with some SBCL-specific code, because we don't want to be programming an SBCL dialect, because it has no explicit specification, and may change in the future
16:39:15
jackdaniel
from the programmer perspective it is useful to know the compiler extensions, but is calling different compilers with extensions of the same language "dialects" useful?
16:39:27
phoe
(and often does, via so-called minor incompatible changes and unannounced changes in its internal structure)
16:39:28
jackdaniel
that would probably mean, that there is no single implementation of the language, only "dialects"
16:42:15
_death
jmercouris: also, since Common Lisp leaves implementations free to implement things differently in many cases, we should be wary of relying on the specific choices made in this implicit SBCL dialect.. programs overspecify
16:43:16
beach
In fact, the standard (perhaps not always intentionally) leaves a lot of things unspecified.
16:44:18
beach
I think that's how people should spend their energy instead, i.e., try to define a standard with fewer things unspecified, rather than one with more or different stuff in it.
16:45:25
_death
beach: I agree.. and also there are many gotchas that may need fixing.. but I'd rather stick with this standard because I see what other people want to put in a new standard ;)
16:46:13
beach
I promise not to put anything new, perhaps with the exception of package-local nicknames, in WSCL.
16:46:55
beach
And maybe the semantics of special variables in the presence of threads, without requiring that threads exist.
16:47:43
_death
beach: personally I see issues with package-local nicknames (I think I explained them here in the past).. I haven't used them anywhere, though I can imagine there might be a case where I would
16:49:20
_death
when I see phoe using a:foo here to say something about alexandria, I think it's a symptom ;)
16:50:50
phoe
https://github.com/search?l=Common+Lisp&o=desc&q=local-nicknames&s=indexed&type=Code for github
16:52:53
_death
although it has different implementations.. but no spec, so beach's work may be useful there
17:01:20
jackdaniel
and as we've heard, modern lisp is being ported to gerbil scheme as it bitrots ,-)
17:01:52
beach
I would get started with WSCL if I could just get the dpANS as a single LaTeX document (containing multiple files obviously) rather than a custom TeX document per chapter.