freenode/lisp - IRC Chatlog
Search
17:33:02
jasom
Just so I don't reinvent the wheel; is there a library for giving the number of weekdays between two timestamps?
18:01:08
aeth
Fortunately, it's not as bad as it sounds because there are only about a dozen or two years. I guess there would be 14: a Jan 1 with each day of the week and the presence or absence of Feb 29. Intervals that cross multiple years could complicate things, though.
18:42:15
jackdaniel
https://github.com/McCLIM/McCLIM/blob/master/Core/clim-basic/extended-streams/text-formatting.lisp#L187
19:11:44
jackdaniel
ACTION desperately tries not to make a joke about comparing whose (implementation) is longer
19:38:38
jasom
xristos: I'm already using local-time, but it only has a single difference function and that only gives you the floor of the difference in years
19:49:45
_death
jasom: your best bet is to look at emacs's calendar code.. the authors also wrote a book called Calendrical Calculations and someone ported some of the code to CL https://gist.github.com/perusio/6687883
20:08:30
Xach
it is available online used for a few dollars. i think i will get a copy sometime soon.
20:08:36
ecraven
and the code is well-written, I "ported" it to Scheme (mostly just rewrite a few macros)
20:09:44
ecraven
I contacted one of the authors years ago about the Scheme port, he was very friendly, though I don't remember what he said exactly about the license
20:10:43
ecraven
ok, found the emails, he suggested that the port would still need to adhere to the original license (free for non-commercial use, I think)
20:13:10
ecraven
well, in theory, you could read the book (but not the code) and just implement the calculations yourself (depending on what exactly you need)
20:13:26
ecraven
the actual calendrical calculations are not so complex, mostly the sun/moon stuff is hard
20:14:08
ecraven
for number of weekdays, you "just" need to convert to rata die, calculate the difference, then check the weekdays
21:59:37
jasom
which is fine for my use case of "dozens of deltas with a difference of no more than a few months"
23:16:10
jasom
most of the ranges are on the order of a few days, so I don't see how precomputing would help
23:22:20
aeth
_death: There are, afaik, only 14 years. Jan 1st on each day of the week and the presence and absence of Feb 29th. So you could just store those and have rules for ranges that span multiple years.
23:23:00
aeth
holidays can be a separate pass, just subtract 1 if the holidy is in the range and on a weekday
23:28:15
_death
well, it's just a popcount to get weekdays in the representation I'm thinking of.. you could have one bitset for each calendar and union/intersect if needed
0:03:52
aeth
I was thinking about a "perpeutal calendar", which, as that page says, is a lookup table
0:07:12
aeth
_death: as I said, you can do a second pass to subtract holidays if it falls in the range.
0:11:58
_death
so having a bitset representation is convenient to allow such ad hoc changes.. in fact it could be made into a project resembling the time zone database, and become useful to many people.. maybe there's already a project like that
0:15:48
_death
though such a project could get more ambitious and need a more complex representation to support all kinds of annotations
0:32:27
MichaelRaskin
Note that some _parts_ of Germany have a ton of holidays of form Easter+N. The original meaning of holiday, yes. Different parts seem to have different amounts.
0:32:59
aeth
If you keep a database of holidays, congratulations, you have now chosen the project that will occupy you for the rest of your life.
0:33:45
MichaelRaskin
Then there is Russia where it is completely normal to have a working Saturday to bridge preceding Tuesday holiday with preceding weekend
0:35:48
Bike
this dream i had once where if you wrote something unoriginal you'd be eaten by a nuckelavee.
0:36:34
MichaelRaskin
This reminds me the story about greetings in an IRC channel where posting a line that has ever been posted leads to a kick
0:37:42
aeth
MichaelRaskin: alternatively, you can start with the most common line in any channel and work your way down from there...
1:05:19
aeth
srandon111: clisp is a great short name for Common Lisp, but unfortunately, CLISP is an implementation (and not the most popular one), so we tend to use CL
1:08:42
aeth
pjb: or you could call it, as a long name... COMMON Object-oriented Modern Mathematical Omnipresent Necessary Lisp
1:11:49
White_Flame
COMMON Object/Mathematical Manipulating Operational Notation LISP Integrating Symbolic Processing
1:15:02
aeth
I do like how that does explain everything you can do with it, too. OOP, functional programming ("mathematical"), and macros ("symbolic processing")
1:33:43
White_Flame
it's not as explanatory, but if doing & figuring out how it works is more your learning style, that can be good
1:35:10
White_Flame
as a learner, the differences between the various implementations aren't going to be noticeable
1:35:28
White_Flame
SBCL is certainly the most popular here, though, because of the fast code it generates
1:35:46
aeth
SBCL is more popular than CCL which is more popular than the rest, but of course exact numbers would be hard to find
1:36:05
srandon111
ok another thing... are there any advantages in learning common lisp wrt to clojure... i mean interms of libraries and modernity?
1:36:10
White_Flame
CCL had much stronger cross-platform support than SBCL, but I think the latter has basically caught up
1:37:35
White_Flame
and if you're working with Java libs imported into clojure, you're going to be dealing with Java-isms all the time, which is a downside
1:37:56
aeth
As far as "modern" dynamic languages, what you tend to get are gradual typing (SBCL has this, through type declarations) and some form of embedded regex (CL doesn't have this, but you could just write a trivial reader macro on top of cl-ppcre or something else
1:38:09
aeth
Maybe JSON in the standard library too but that's so unimportant when every other language has like 5 JSON libraries
1:38:42
White_Flame
lisp's "package manager" is called quicklisp, and has some thousands of libs easily loadable
1:39:05
Ober
White_Flame: interesting... I can't find reference to it in the clhs, or the spec... :P
1:39:07
White_Flame
lisp was a bit late to the party on that one, primarily because it's pretty easy to roll your own stuff and there's less reliance on libs
1:39:25
aeth
I guess modern could include package managers (CL has these) as well as system threads (so you can use all 16 cores or whatever you happen to have) and CL doesn't have threads in the standard, but nearly every implementation has them, and you can portably use them with bordeaux-threads
1:40:01
aeth
another thing about modern is Unicode, which, yes, most CLs have. Most implementations are (or at least can be) 64-bit, too.
1:43:36
aeth
White_Flame: well, no, most languages (Python 3 excluded) keep backwards compatibility, and you rewrite your code because of the libraries changing, not the language. Sort of like how the Linux API is stable but that doesn't mean that your 1995 binary will still run, because of the libraries.
1:44:35
Ober
funny thing, gf had an unopened Navigator 1.0 box, still in shrinkwrap. the binary for bsd ran still on x86 netbsd...
1:44:41
aeth
I guess some languages deprecate, but they tend to err on the side of having the same feature implemented 5 times but only the newest one implemented well, just to avoid breaking old code
1:45:28
White_Flame
but taking JS as an example, the language is pretty messy, and thus the libs redefine the programming environment to make it "better", so the frameworks tend to be more definitive than the lanuage. That also includes polyfilling and such so that the underlying language becomes more hidden
1:46:41
aeth
I just haven't seen anyone do that outside of https://github.com/cl21/cl21 which no one uses
1:47:20
aeth
People probably reject dramatic redifintions of the language because CL gives you so much freedom, so such libraries are completely incomprehensible and might as well be new programming languages
1:47:49
White_Flame
and it's the opposite in JS because people fundamentally hate the base language they're forced to use ;)
1:49:45
White_Flame
since there's no fallback or anything. The output must be valid in the lower language
1:50:16
aeth
that doesn't mean anything, though, since you can use a reader macro to essentially completely change everything
1:50:29
Ober
for me running a clojure shop, the cto wanted to do all the CL ways with it, but in the end it's just java.
1:52:25
White_Flame
I have it bookmarked, but I don't know clojure yet so I don't know how well it works
1:55:03
aeth
eww, I don't know what's worse, that it uses .lisp for clojure files or that Github detects it
1:55:49
aeth
it uses the same library as Gitlab so that might explain why most of my Scheme is erroneously being identified as Scheme. My macros are too good at faking Scheme from CL.
2:21:01
no-defun-allowed
I use them enough that not having them could be annoying, but I don't try to use them frequently.
2:22:34
no-defun-allowed
In my opinion, the interactive environment is well above average (it could be better, but it's still superb).
2:24:24
no-defun-allowed
Here is a use of a macro I wrote that defines a program for my bytecode interpreter: https://gitlab.com/cal-coop/netfarm/netfarm/-/blob/master/Tests/benchmark.lisp#L77
2:25:59
no-defun-allowed
I guess the macro is trivial enough, in that (define-script name constants . body) expands to (defparameter name (compile-program constants body)), but having the code be normal lists and symbols instead of some other structure makes writing a program fairly simple.
2:26:24
phadthai
I like that it's fast for prototyping without caring about optimization and then it can be worked in where too slow; I like the interactive and incremental development; I like that for every problem that can be expressed more elegantly it doesn't always mean needing to rewrite a language or config parser or interpreter sacrificing performance (macros are great there)...
2:28:10
phadthai
there are things to dislike of course too, on some very small systems, if not wanting cross-compiling, lisp might just be too heavy vs another interactive language like forth
2:28:17
White_Flame
the thing is, many languages have taken on aspects of lisp (first class functions, GC, rich numeric stack & type system, REPL, etc) but none integrate it together as well as lisp does, because their code forms are not plain data
2:28:47
White_Flame
syntax becomes the enemy when you're running code at compile-time, or transforming data specs into runnable code
2:28:58
phadthai
another is that popular languages have tons of libraries that may lag behind for lisp or just be too sparsed among disparate individual developer repositories, the work to interface to other stuff like FFI can be challenging at first too
2:29:26
no-defun-allowed
There are also compilers (not batch compilers, like gcc or ghc, they can be invoked at runtime) that produce decent machine code for unoptimised programs, which as phadthai says, lets you leave the most optimisation for the slowest parts.
2:30:45
no-defun-allowed
There's a lot of context you would want, but I have a bytecode interpreter which can be run by other people over a network to do things reproducibly.
2:31:39
White_Flame
lisp is a great language to create small embedded utility languages inside of it; and/or create new high level languages on top of it and not worry about machine code details
2:32:02
White_Flame
if you haven't hit the limits in other langauges yet, it's nearly impossible to describe the benefit
2:32:33
no-defun-allowed
Okay, another one. You can invent your own namespaces in Lisp using macros, which IMHO is a bit cleaner and more general than using decorators in Python.
2:33:56
aeth
srandon111: It depends on what you're doing. Sometimes what you're doing is best expressed as a macro.
2:34:30
phadthai
it's a compiled language that evolved many dynamic aspects, as such it's also interesting: can be surprisingly fast with good code on a good implementation, while at the same time very dynamic; things like the distinction between defvar and defparameter are also important, it decides what happens at image load time or when recompiling some code in a live interactive image
2:34:38
srandon111
no-defun-allowed, aren't you talking about namespaces as i know them in java/ and so on?
2:34:55
aeth
srandon111: Once you're used to macros (which takes a while) a macro is just list traversal. The hard part is making it look like it was built into the language so people can actually read the macro. What you don't want is something like LOOP, but e.g. writing your own CASE with a different quality test is perfectly fine
2:35:42
no-defun-allowed
Say you have a web server framework, and you want to define a function for handling some page. In Python you might write @get("/url") def url_handler(...): ...
2:36:01
no-defun-allowed
In Lisp the framework could write (define-easy-handler (url-handler :url "/url") ...)
2:36:13
srandon111
no-defun-allowed, since i think this thing about macro is quite questioned by noobs like me... isn't there a website/resource which tries to explain the benefits with examples?
2:37:10
aeth
no-defun-allowed: right, properly written macros look more built-in than other a lot of other languages' metaprogramming, particularly C++<template<template<template<template... and Python/etc. @stuff
2:37:30
phadthai
and in lisp the html templates can result in much native code (much processed at compile time) vs all interpreted
2:37:37
aeth
And if you use the right names, nobody's going to confuse a macro and a function, especially since a macro probably should have a &body
2:37:49
aeth
And since you can see the API in something like Emacs, if you see &body you know it's a macro
2:38:45
srandon111
aeth, yes most likely i am missing all this stuff since i still don't really know well lisp
2:38:51
aeth
phadthai: right, any kind of HTML template system is either going to turn into a constant string at compile time, or (if it takes in input) it's going to generate something more or less like a FORMAT string
2:39:30
White_Flame
srandon111: simple case: You want to add instrumentation to your code, to track execution for profiling, coverage, whatever. The desire is "Every time I define a function, I want it statically recorded somewhere in a table, and on entry/exit it should call code and report on its parameters automatically. It's a right pain in other languages; in CL you simply wrap DEFUN in another macro
2:39:47
aeth
srandon111: I think Clojure is more culturally against macros than Common Lisp is. In Common Lisp, it's fine as long as it fits a simple pattern, like WITH- (usually wrapping an UNWIND-PROTECT, but sometimes just a LET), DEFINE- (almost always ultimately just a DEFUN), etc.
2:41:52
aeth
I kind of hate the DO-FOO pattern a bit because that can get annoying... iterators in LOOP (which aren't a thing) would be a lot more convenient
2:41:56
White_Flame
srandon111: and that DEFUN macro can look at the _source code_ of the DEFUN, and handle the name, the literal parameter list, etc, and generate the _source code_ which performs all the registrations and wrap the body source code of the defun wiht the tracking stuff
2:42:52
aeth
In general, the scariest macro you're going to see is a DEFINE-FOO that is built on DEFINE-BAR that is built on a DEFINE-BAZ that is built on a DEFINE-QUUX ... etc. that ultimately is a DEFUN
2:43:54
White_Flame
and that transformation is just plain lisp code, which can call all the same utility functions etc (as long as they're there at compile-time)
2:44:38
White_Flame
you can literally have your own DEFUN that source code will syntactically use, by setting up your packages right
2:44:47
no-defun-allowed
Usually a macro makes the language one works in "higher level", by allowing the client to ignore how it's implemented.
2:44:51
White_Flame
or, you can have DEFUN* or whatever variant that you specifically use intentionally
2:45:10
aeth
There's exactly one time when a macro is really, really bad and that's code-walker macros. No one does them correctly. Imagine a macro that walks through the source and replaces all (foo 42) with "Aeth is the best programmer because Aeth writes the most clever macros." There are so many ways that can break.
2:45:28
no-defun-allowed
It's more of a case of "I don't want to know", rather than "I don't get to know"; but MACROEXPAND (or the macroexpander mode in SLIME, invoked using C-c M-e) lets you figure out what the macro does.
2:46:11
White_Flame
and building onf n-d-a's comment, Lisp is one of the only runtime-compiled languages that actually lets you drill allt he way down to the assembly language to see what's going on