3

As a continuation of Using Lisp or Scheme for runtime configuration of Java programs, I am looking at having a Java property file "replacement" which can contain code in addition to plain Java strings. Java property files look like:

key1=value1
key2=value2
...

For fun I am playing with an elderly JScheme (due to size) but came to think of that it would be useful to have a file format that would be compatible with Clojure. This would allow the usage of the same syntax for just small "read my configuration"-usages as well as larger systems using Clojure. The idea is then that the values can now be evaluated instead of just being static strings.

I am not very experienced with Scheme or Clojure, but it appears that vector is available in both, but the short-cut syntax is different (#(...) compared to [...]).

Is there a syntax for representing a "Java property" data structure which is both valid Scheme and Clojure programs? Please show actual code.


EDIT: After looking at the (props ...) suggestion and brushing up my Lisp skills some more with ELisp and JScheme, I found that

(list 
 "key1" "value1" 
 "key2" "value"
 )

might be the simplest way to do this with a syntax not too far from a property file.

Community
  • 1
  • 1
Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347

3 Answers3

3

Assuming you don't want to create scheme reader macros to read clojure map literals (and clojure doesn't support custom reader macros), how about defining a "props" function:

(props 'key1 value1 'key2 value2 ...)

Now in clojure define props as

(def props hash-map)

and similarly in scheme, then you can just eval the props expression in either language.

you can get a bit more funky and make props a macro that quotes the keys (assuming the keys are symbols) or leave it as is and get more flexibility at the cost of having to quote the keys.

Joost Diepenmaat
  • 17,633
  • 3
  • 44
  • 53
3

The easiest and most portable way of doing this is with a good, old-fashioned list S-expression. Use write (Scheme) or pr (Clojure) for writing and read (both Scheme and Clojure) for reading. (There is no need to use eval.)

Your example would look like this as an S-expression:

("key1" "value1"
 "key2" "value2")

S-expressions are pretty flexible. They can be nested arbitrarily and may contain objects other than just strings. For instance, if the keys are semantically struct fields (analogously to XML element names), symbols might be a better fit than strings for those, as in the following:

(game
  (players (name "Alice"     score 5)
           (name "Bob"       score 10)
           (name "Catherine" score 20))
  (state 4321))
Matthias Benkard
  • 15,497
  • 4
  • 39
  • 47
0

Assuming you want to be compatible with Clojure, I think best structure and format to emulate a Java property file would probably just be to use the standard Clojure map syntax.

Advantages:

  • It's very JSON-like, a general purpose and flexible format
  • You can just read it directly through the Clojure reader (with read-string or similar). No need to write any parsers!
  • You can also include Clojure code in the data structure, which can be read in and compiled by the Clojure reader (though be careful about code injection attacks if you do this!)
  • You get all the benefits of it being an immutable persistent data structure

Syntax would be something like

{:key1 "Value1"
 :key2 "Value2"
 :function (fn [x] (* x x))}

You can use any object you like as the keys (e.g. Strings) although I personally think it's easiest to stick with keywords (i.e. the symbols starting with a colon). Keywords have some nice advantages in that they are reliably interned and you can use them as functions which get their value from the map, e.g.

 (:key2 property-map)
 => "Value2"
mikera
  • 105,238
  • 25
  • 256
  • 415