This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-09-25
Channels
- # alda (7)
- # aleph (10)
- # announcements (3)
- # babashka (103)
- # beginners (54)
- # calva (62)
- # clerk (2)
- # clj-yaml (27)
- # cljs-dev (1)
- # clojure (61)
- # clojure-europe (64)
- # clojure-nl (3)
- # clojure-norway (34)
- # clojure-sweden (4)
- # clojure-uk (4)
- # conjure (9)
- # cursive (1)
- # data-science (3)
- # fulcro (20)
- # gratitude (1)
- # hyperfiddle (54)
- # lsp (9)
- # malli (7)
- # meander (4)
- # membrane (17)
- # off-topic (23)
- # releases (3)
- # sci (1)
- # shadow-cljs (5)
- # sql (1)
- # tree-sitter (8)
- # vim (6)
I’m trying to count unicode code points. Not sure why the following works in Java but not in bb:
(.count (.codePoints "woof🐕"))
java=> 5
bb=> java.lang.NoSuchFieldException: count [at <repl>:13:1]
in bb v1.3.184, clojure 1.11.1 Java 20.0.2
bb is based on JDK 19, does this method exist at that version?
this is just a matter of adding the right class to the class configuration in babashka, it's just not included yet
Not sure when this was added, the Java APIdocs mention it in Java SE8: https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#count--
Though that documentation looks suspicious;; pretty sure `
return mapToLong(e -> 1L).sum();
is not valid java 8It’s relevant if count was added in jdk20. but I’ll add an issue later today
I don’t understand the java8 documentation 🙂 so I don’t know. I’ll do some experiments first to see when that was added.
yeah looks like its added on java8
Ok i’ll add an issue later today. Thanks!
actually the Stream class also has a count method, so I'd expect this to already work somehow...
somehow this doesn't work:
(let [^java.util.stream.Stream x (.codePoints "woof")] (.count x))
Stream seems to be a sibling of IntStream
adding the class + a cast from a private object to that class seems to work:
$ ./bb -e '(.count (.codePoints "woof🐕"))'
5
@U09N5N31T This currently works in bb as a workaround: (count (iterator-seq (.iterator (.codePoints "woof")))) => 4
fixed here: https://github.com/babashka/babashka/pull/1625 use the recommend workaround meanwhile
lol, this test succeeded in the PR but on master:
lein test :only babashka.interop-test/IntStream-test
FAIL in (IntStream-test) (interop_test.clj:46)
expected: (= 5 (bb nil "(.count (.codePoints \"woof?\"))"))
actual: (not (= 5 6))
Apparently there is something weird with codepoints on Windows. I'll just change the test to pos?
Maybe something is off in the source file encoding?
just use this for now as a workaround: (count (iterator-seq (.iterator (.codePoints "woof"))))
- your original code will work only from the next release on
I will thanks!
Is anyone who's used (preferably dug into the code of) awyeah-api
for using Cognitect-style calls within babashka about? I'm trying to execute a request against the AWS API, which works in the actual Cognitect libs. I'm already executing various other requests (including against SecurityHub), which work with awyeah-api
.
My bb.edn
contains:
:deps {com.cognitect.aws/endpoints {:mvn/version "1.1.12.504"}
com.cognitect.aws/securityhub {:mvn/version "848.2.1413.0"}
com.cognitect.aws/sns {:mvn/version "847.2.1365.0"}
com.grzm/awyeah-api {:git/url ""
:git/sha "9257dc0159640e46803d69210cae838d411f1789"
:git/tag "v0.8.41"}
org.babashka/spec.alpha {:git/url ""
:git/sha "8df0712896f596680da7a32ae44bb000b7e45e68"}}
The request I'm trying to execute is:
(require '[com.grzm.awyeah.client.api :as aws])
(aws/invoke
(aws/client {:api :securityhub})
{:op :BatchUpdateFindings,
:request {:FindingIdentifiers [{:Id "arn:aws:inspector2:eu-west-2:${MY_ACCOUNT_ID}:finding/e7fcfd57f44eac3fcf45419912f99b14",
:ProductArn "arn:aws:securityhub:eu-west-2::product/aws/inspector"}],
:Note {:Text "Status changed from NEW to NOTIFIED", :UpdatedBy "DanM testing"},
:Workflow {:Status "NOTIFIED"}}}))
I get back a NullPointerException stacktrace from the awyeah http-client (it's long, so I'll put it in a thread on this message)Oh, of note is that I'm using exactly the same com.cognitect.aws/securityhub
version in full Clojure with the real Cognitect lib, where it works
That stacktrace doesn't seem to contain anything from within awyeah-api, it's all just sci and Java proper, from what I can see...
aaah makes sense. I bet @U0EHU1800 would accept a PR for that
I know my request is a :patch
request, so I think we're looking up into there are getting back a nil
method
He actually has a PR template that explicitly says he doesn't accept PRs and to raise an issue 😉 But I can do that too no worries once I've proved it
Fixed in https://github.com/grzm/awyeah-api/commit/465cacdbe0abd7692987b166c3b7d2134bc62aff Thanks for the detailed report!
Awesome, thanks very much @U0EHU1800 😄
I'm sometimes tempted to make a language front-end to babashka which uses JS or Java-ish syntax so people in those languages can script in babashka, but every time I end up with the conclusion that they should just learn Clojure and nowadays just paste their inputs into ChatGTP to get started ;)
https://docs.racket-lang.org/rhombus/index.html You might look into Rhombus, an experimental version of Racket that provides a more "conventional" syntax for Racket s-expressions, though it is more similar to Python (e.g. syntactically significant indentation) than JS in its notation.
> Are you talking about a JS to Clojure(SCI) compiler/interpreter? I'm talking about a JS/Java-ish to Clojure transpiler which is then being fed into bb. So same APIs, just different syntax
I think Java (or Kotlin) syntax might make most sense as people who already know the JVM might be more tempted to use bb
I have to admit that I find my use of clojure spurned by my colleagues even if I show that I can perform tasks fast with it.
->(foo(), ..., ...)
not even sure how to express keywords, it's gonna be a shit show probablyWould you be better starting out with something like C, so that you don't have the weight of classes etc.
I'm considering doing more reaching out to non-Clojure developers for babashka, but I wonder if there's any real interest in this from non-Clojure people. I could imagine that there's JVM developers that want to build there bash-like scripts in something they could easily read and still also use JVM interop in places
re: the threading example, I think the method chaining is a viable translation, of course the question becomes are keywords an acceptable departure from 'familiar' syntax, and maybe will keywords make sense in method position... I could imagine a really verbose translation that could probably be Java being something like foo().get(new Keyword("bar")).get(new Keyword("baz"))
, and maybe somewhere in that spectrum is what's comfortable for a "Java audience".
To be clear, I'm not saying this is a desirable outcome per se', but something like a colon could be a (stretched) version of Kotlin's operator overloading. Just to sort of make the argument that a colon followed by a symbol could be somewhat correlated to a curly-braced dialect, I overrode !
on Strings in Kotlin to produce this code which 'works'™️ :
data class Keyword(val name: String)
operator fun String.not() = Keyword(this)
operator fun <T> Map<T, *>?.get(k: T) = if (this != null) this[k]
else null
val m = mapOf(!"bar" to mapOf(!"baz" to "abc"))
m[!"bar"][!"baz"] // "abc"
m[!"bar"][!"bat"] // null
it's not perfect (probably not even good), but it could be a step toward saying "`:abc` could be shimmied into a curly-brace language"
I’ve been thinking about an alternative infix syntax for Clojure for awhile. For what it’s worth, I think something like rhombus or dylan would be a better starting point than a Java-derived syntax.
you can already see how hard it is to properly expose Clojure to a mainstream dialect
In the language could you do the resolving through some kind of import header syntax and so remove the need to the resolve and helper functions?
@U4C3ZU6KX this works now ;)
if you are exposing the idea of a keyword in this mini language why not just use :
or do you have to expose the idea of keywords? Also is the idea of a keyword as a function really working in that last example, it seems quite subtle to me.
this doesn't work for calling pr-str
in Clojure: ((symbol "pr-str" ...))
but
s`pr-str`(...)
translates into
(pr-str ...)
because the conversion is done at compile time