databricks / sjsonnet

Apache License 2.0
266 stars 54 forks source link

Java in-memory idiomatic wrapper #157

Open jshook opened 1 year ago

jshook commented 1 year ago

I've been using the java interop pattern. However, I need to be able to process a text image that may or may not be in a file. I do understand that the Path abstraction roots the usage pattern into the filesystem view, which is very appropriate for most cases. However, it would be much better for my use case to be able to access the Interpreter core via a simple and idiomatic Java wrapper that doesn't indirect through the argv pattern. It seems that this would be useful in other places.

lihaoyi-databricks commented 1 year ago

Folding in https://github.com/databricks/sjsonnet/issues/157, whatever idiomatic Java API emerges should also include a way to pass additional functions to std

sandys commented 1 year ago

@lihaoyi-databricks are we able to use this functionality today? given #166 is merged. we are using sjsonnet functionality in a java library and are trying to call java functions during jsonnet execution.

will live with a hacky way today and then use ur standardized java api when it is ready

sandys commented 1 year ago

@lihaoyi-databricks we tried subclassing std and adding a new function in it. the issue is that the new function is not being picked up (when we pass the new std to main0). Would appreciate any help in how to do this.

lihaoyi-databricks commented 1 year ago

@sandys it looks like std has a val functions: Map[String, Val.Func] that lists out all the functions. Did you add the newly defined function to that list?

sandys commented 1 year ago

@lihaoyi-databricks thanks for replying - appreciate it!

we are not able to add our function to it - we tried called "updated" on it, etc but didnt work. so we switched to trying to add a function to std().

would you be able to help ? even a trivial java side example would be super useful. P.S. we are already using the 0.4.5 RC

lihaoyi-databricks commented 1 year ago

You need to do something like override val functions = super.functions.updated(...) I think

I haven't actually tested this yet, so try it out and let me know if it doesn't work

sandys commented 1 year ago

@lihaoyi-databricks im actually using sjsonnet from java code. i think your code is scala..but i tried variations of this using java and it doesnt work :(

lihaoyi-databricks commented 1 year ago

Can you define a small Scala module to do this and then call it from Java? If not, you'll have to wait until an implementation of this ticket is available

sandys commented 1 year ago

we have a whole bunch of java functions that we want to use from within jsonnet. im happy to migrate to your solution when it is available, but is there even a hacky way to use it today ? im happy to shuffle a lot of code on my java side to make it happen temporarily.

lihaoyi-databricks commented 1 year ago

If you're happy with hacky and this is urgent for you, you can fork this repo and add your std.foo functions in the Scala code that can call your Java functions, then publish your own artifacts to maven central or your own assembly jar that you can use within your project.

sandys commented 1 year ago

xtrasonnet is a fork of sjsonnet that adds support for adding additional functions.

https://github.com/jam01/xtrasonnet/blob/0.5.4/xtrasonnet/src/test/java/io/github/jam01/xtrasonnet/spi/LibraryTest.java

aelfric commented 6 months ago

You need to do something like override val functions = super.functions.updated(...) I think

I haven't actually tested this yet, so try it out and let me know if it doesn't work

I was looking for how to define custom functions in Scala.

Even in Scala this doesn't seem to work. With Scala 2.13, there is an error "super may not be used on value functions". I think maybe if we want to be able to override the functions map, it needs to be a lazy val.

aelfric commented 6 months ago

It seems the solution in Scala, at least, is to use an early initializer.