@slipset has joined the channel
Welcome @slipset;)
Thank you 🙂
Actually I thought of something that you could help with opinion-wise
Shoot
Lingy(Perl) has OO interop...
Let me repl a couple things. sec
user=> (import YAML.PP)
YAML.PP
user=> (println (.dump_string (.new YAML.PP) [2 3 4]))
---
- '2'
- '3'
- '4'also perl eval...
user=> (perl "for my $i (1..4) { print \"$i\\n\" }; 123")
1
2
3
4
123
user=> the 123 was to hide a bug I just found 😄
I see that in difference to Clojure, you treat new as a fn (or method). Which makes sense for Perl I guess because it is just that.
In Clojure you’d write (YAML.PP. )
sorry had to file bug: https://github.com/lingy-lang/lingy/issues/55
user=> (println (.dump_string (YAML.PP.) [2 3 4]))
---
- '2'
- '3'
- '4'
nil🙂
-> FAIL Installing Time::HiRes failed. See /Users/erik/.cpanm/work/1690475412.86147/build.log for details. Retry with --force to force install it.
-> FAIL Installing the dependencies failed: Installed version (1.9760) of Time::HiRes is not in range '1.9764'
-> FAIL Bailing out the installation for Lingy-0.1.19.
😞is that cpanm Lingy?
yes
trying on my M1
erik@keep % perl --version
This is perl 5, version 30, subversion 3 (v5.30.3) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)
Copyright 1987-2020, Larry Wall With a very fresh cpanm install
erik@keep % cpanm --version
cpanm (App::cpanminus) version 1.7046 (/opt/homebrew/bin/cpanm)
perl version 5.030003 (perl) worked here 😕
I get it
sec
That's my fault and I will fix it fast but can you try something?
Run cpanm --look Lingy
puts you in a subshell
edit Makefile.PL and set the Time::HiRes version to "0"
then run cpanm .
if you don't mind
Getting there
erik@keep % lingy -D
Please install Term::ReadLine::Gnu from CPAN
erik@keep % do it 🙂
I had to not dep on Term:Readline:Gnu because of windows issues
But the lingy --repl needs it
How do I install that? Perl n00b
cpanm 🙂
D’oh, ReadLine not Readline
M1 Macbook Pro
user=> (macroexpand '(YAML.PP.))
(. YAML.PP new)
user=> (macroexpand '(.new YAML.PP))
(. YAML.PP new)
user=> @slipset anyway, in Java everything's an object. so interop is straightforward. In perl the data types are operated on with syntax, operators and keywords.
I want to make a library/namespace for all the keywords
Basically what's in *CORE::
user=> (perl "pack 'WWWW', 65, 66, 67, 68")
ABCDRight, where pack is an operator or somthing?
I would do
(pl/pack "WWWW" 65 66 67 68)yes!
pack is a perl keyword func
perldoc perlfunc
Ok awesome
It’s been probs 20 years since last time I programmed Perl, so I’m a bit rusty 🙂 I also remember pack as one of the harder things to grok 🙂
I was talking it over with @pez a couple days ago but good to know you agree
So one of the things that Clojure is struggeling with which I believe is being worked on is stuff like:
user> (map Math/abs (range 3))
Syntax error compiling at (*cider-repl ).
Unable to find static field: abs in class java.lang.Math
user>
Which is just plain old annoying 🙂@slipset I don't really get why that doesn't work
Can you explain?
Not really. And it’s dinner time :)
Bon appetit 🙂
I think there is a fine line in interop between exposing too much of the idiosyncrasies of the host and hiding too much of them.
Like, from a Clojure point of view I don’t care if Perl has syntax or operators or keywords for doing a thing, I’d just like to gloss over that and perhaps say (perl/+ 5 6) (stupid example since + is in clojure.core.
But it’s also very annoying with leaky abstractions and you’d have to remember that because + is an operator in Perl it behaves slightly different than what pack does since pack is a keyword func.
(if that were the case, I’m being hypothetical here)
(pl/-f path)
Still trying to suss out why (map Math/abs (range 3)) fails
Yah, but you’d might want to expose that throuh clojure.io.perl or something to mimic clojure.io.java
nod
(this is really helpful btw) 😄
But then again, do you expose -f through both clojure.io.perl and perl/-f The former would be for the convenience of the Clojure programmer, the latter for the convenience of the Perl programmer 🙂
Perhaps both?
yep
Lingy starts quickly 🙂
it would be lingy.io.perl or lingy.io.host
And I saw you asked about cljc files. I believe that @borkdude implemented reader conditionals for babashka, you probably want that for lingy as well.
$ time clojure -e '(time 42)'
"Elapsed time: 0.012903 msecs"
42
real 0m0.964s
user 0m2.334s
sys 0m0.085s
$ time lingy -e '(time 42)'
"Elapsed time: 0.07 msecs"
42
real 0m0.136s
user 0m0.108s
sys 0m0.029sclojure is much faster after starting
(for now 🙂 )
At some point in time I implemented an http client in an early version of https://github.com/planck-repl/planck because I wanted to use it for some simple scripting which needed http/get now, now would I go about using something like Perl libwww (I guess) if I wanted to do (http/get " from lingy?
I'd have to try. The perl interop is still a wip. Some things don't work as expected. All Lingy data values are class objects so things need to be boxed and unboxed. Some works some not.
And more ideas for free. One thing that Plank was missing at the time was some way to define the packages your program depended on. So It would be neat if lingy had something deps.edn like that also understood how to depend on cpan stuff.
already been discussing that with @seancorfield 🙂
Shadow.cljs has achieved the analogous for NPM; perhaps there is a model to consider
In re the namespaces for common affordances... There is also a pattern. clojure.core and cljs.core are twins. Likewise clojure.pprint and cljs.pprint, clojure.reader and cljs.reader, and a few others. The ClojureScript compiler accepts code that require's http://clojure.xyz, by using http://cljs.xyz instead. This eases writing portable Clojure-ish programs.
In re using Math/abs as if it were a function: in Clojure first-class functions are objects implementing IFn and Math/abs is not such a thing. (macroexpand-1 '(Math/abs 42)) shows (. Math abs 42). But Math (full name java.lang.Math) is host interop, no expectation of similarity on another host.
I pay attention in about 15m
Here now
@phill Lingy is intending to use clojure/core.clj directly. It does so partially now: https://github.com/lingy-lang/lingy/blob/main/perl/lib/Lingy/core.clj
Lingy maps Clojure clojure.lang. namespaces to lingy.lang. equivalents and known Java classes to Perl counterparts
Since Lingy intends to be multi-host I am considering some class name porting to go from java.lang. to host.lang. instead of perl.lang.
whatever the best ways are to get the most use and least duplication out of source files.
Thanks for the insights re the java native Math class
@phill if it were a clojure.lang.Math class then it would implement IFn, right?
Er - All (fn ...) implement Clojure's Java interface "IFn" and I'm sure the Clojure inventors would have made host functions (Java "static methods") first-class if they could figure out how to do so. If a Perl sub {...} could be a first-class function in Lingy, super!
like java.lang.Long vs clojure.lang.Numbers
At this point Lingy doesn't do compilation. It does make Lingy::Fn objects from (fn ...) forms. and those objects are blessed Perl closures (functions)
but compilation (possibly to a super fast VM) is an intended area of research
and the Lingy data types are all tied objects, not first class. for immutability and methods
I think the area for ideal compatibility is pretty much limited to what's documented at https://clojure.github.io/clojure/ ... minus the "clojure.java...." stuff like http://clojure.java.io. Every host differs in those respects. Presumably someone could make a clever asynchronous I/O package that could be used portably, but nothing with blocking I/O will work in JavaScript. The Java-language underpinnings of Clojure are not replicated in ClojureScript, which sort of sets the tone for other ports. According to rumor, ClojureScript is closer to "Clojure-in-Clojure" on account of having used Clojure protocols internally.
but I want them to become HAMT based things
interesting stuff. I'm glad to have people with this level of insight into clojurescript to chat with as I have very littel experience with it so far. but of course I have been wondering WWCSD? 😉
Somewhere, I saw Clojure contrasted with Ruby in this regard. Ruby wraps the whole host standard library, or so I heard. Clojure wraps almost none of it. A striking example is that the (throw ... (catch ...)) model is standard across Clojure-ish ports but it is not possible to write a portable catch clause. The exceptions are host exceptions. So Perl's $@ would fit right in.
I think a portable runtime library might be very welcome, as an add-on, for convenience where the cost of wrapping was not a concern.
I'm thinking about something called LingyVM that might be that
Re throw/catch the https://github.com/kanaka/mal/tree/master/impls does that the same for about 70+ langs
including ruby
or maybe I misundersand you
they all do TCO too (with a test suite that won't finish if implemented wrong, to prove it)
even though Clojure doesn't have native TCO
Lingy has TCO and recur
Yeah Perl has a very nice goto that can go-to a function
There are some exception libraries for Clojure. I think the core language's ideal was to add no run-time cost. Therefore, it uses host exceptions, whatever those might be.
I thought I had seen everything, and then I noticed that in ClojureDart the "catch" clause has an extra parameter because Dart exceptions have the stack trace external to the exception object.
I learned while making my MAL implementation how perl's goto actually works. Iirc it simply does a return at that point and then calls the subroutine that you goto'd to!
Lingy definitely adds runtime cost at this point but since I am free to compile into whatever I can imagine and make it work, the goal is to make it as fast as C extensions in Perl.
So you get a massive performance gains simply by writing parts in a lisp 😂
Of course doing that and achieving really good interop is definitely a science project
@phill I found that explanation of goto (sub form) in perldoc -f gotot
> The "goto &NAME" form is quite different from the other forms of "goto". In fact, it isn't a goto in the normal sense at all, and doesn't have the stigma associated with other gotos. Instead, it exits the current subroutine (losing any changes set by "local") and immediately calls in its place the named subroutine using the current value of @_.
I thought that was both clever and sane