Clojure platform feedback

Hello! Thanks a lot for Clojure platform.
It is very hard to understand where is matching parenthesis.
Clojure platform definitely needs a rainbow parenthesis support.
At least, make highlighting more contrast in vim’s normal mode.

Hello!
This is a good idea. None of us are Clojure users so we’re not aware of all the little tricks to make coding in Clojure more enjoyable.
We’ll take a look at what we can do.

Thank you for the feedback,
Keep Coding :smiley:

1 Like

First let me say that I’m very happy that you have a Lisp dialect. Clojure isn’t my favourit, but it did give me a good reason to look into it. :smile:

In terms of feedback I would suggest to make the auto generated code a bit more functional. At the moment it looks very imperative and is probably not very helpful for beginners. For example in “The Descent” you need to read in eight numbers and the auto generated code goes out of its way to *not* put them into a list.

It looks something like this:

(let [space-x (read) space-y (read)]
  (loop [i 8]
    (when (> i 0)
      (let [mountainH (read)]
        ;; mountainH: represents the height of one mountain, from 9 to
        ;; 0. Mountain heights are provided from left to right.
        (recur (dec i)))))

You could replace it with this:

(let [space-x (read)
      space-y (read)
      ;; mountains is a list with the height (from 9 to 0) of the leftmost
      ;; mountain, followed by the height of the second mountain from the
      ;; left and so on
      mountains (repeatedly 8 read)]

The Vox Codei - Redux game doesn’t work with Clojure. Even when I use the auto-generated code I get exceptions when running the testcases.

But not every testcase throws an exception. The first tescase works for example.

In most testcases the exception is thrown right at the start. But in testcase five for example it comes at turn 22.

The non reduxed version of the Vox Codei game also doesn’t work with Clojure. The testcases seven and ten are throwing errors. Here is a screenshot.

@chrm if you want that fixed, try summoning admins like @G_Rom @SaiksyApo and stuff.

No need to summon me though for two reasons:

  • I can’t modify the website (I have little power and I only created games)
  • I receive in my mail all forum messages, if I don’t answer, that probably means that I can’t help you since I’m not a website admin.

However, if you need something forum related, I’m almighty, so I can close, move, ban, and even edit your own post (no full code anyone?).

Well I went a little bit off topic but still, there is a lot of messages here so if you have a bug report, please summon the admins, because I don’t think that every one of them have the time to look at all the messages here.

I have the time to read the forum, but I can’t modify the game:)

I reported the bug in our bug list but…

Please change the boilerplate in Clojure, at least in the case of N reads, the current one doesn’t work, and the following in way more functionnal :

(take N (repeatedely read))

The current stack of loops is so wierd it is confusing, clojure is a functionnal programming language not an imperative one.

1 Like

You are right, the autogenerated code for Clojure is pretty bad. I already suggested to change it two months ago here, but I got no response. :-/

PS: you can make it even shorter, (repeatedely N read) does the same thing.

Hey @yenda1, @chrm,

I just moved your posts in this topic instead of CoC related :wink:

yenda1, could you give us an example. (If CoC questions, what was it related to?) We had a regression last sprint, the fix was released few hours after your message.
chrm, we missed your feedback about about using ‘repeatedly’. I just created a note so that we will take time to check if we can use it.

As for vox codei / vox codei redux, we fixed it. Clojure evaluate strings when using (read), so our use of the character ‘#’ to represent the map was not interpreted as we thought.
The input is the same for each languages, hence taking into account any and every languages to forbid some special characters would be too limiting. That’s why some generated code in Clojure might not be pretty.
As an example, how would you read something like: ‘…# .#. #…’, that correspond to 3 rows or 3 characters, separated by spaces, in the same variable named ‘row’? We may have missed a pretty way to do this.

Now I get it. There never was a problem with the game. The autogenerated code and my code just produced the same error for different reasons. :slight_smile:

(defn -main [& args]
  (let [[width height] (with-in-str (read-line) (list (read) (read)))]
    (while true
      (let [[rounds bombs] (with-in-str (read-line) (list (read) (read)))
            rows (repeatedly height read-line)]
        (println "WAIT")))))

Thats the code I was using. There are a two points to note, that together produced a rather cryptic error message that I didn’t understand.

Like you said, the rows can contain # characters, which the reader interprets as reader macros with special syntax rules. So the rows have to be read as strings with read-line.

And second, the list that repeatedly produces is lazy. If it isn’t used the read-line never happens and the input remains in *in*.

Because I didn’t use rows (yet), the lines never get read. Consequently the read that should read the rounds or bombs for next turn might find a #, which is the same error the autogenerated code had.

With a small change everything works as expected :slight_smile:

(defn -main [& args]
  (let [[width height] (with-in-str (read-line) (list (read) (read)))]
    (while true
      (let [[rounds bombs] (with-in-str (read-line) (list (read) (read)))
            rows (doall (repeatedly height read-line))]
        (println "WAIT")))))

Or if you prefer without the destructuring forms.

(defn -main [& args]
  (let [width (read) height (read) _ (read-line)]
    (while true
      (let [rounds (read) bombs (read) _ (read-line)
            rows (doall (repeatedly height read-line))]
        (println "WAIT")))))

The important part is to wrap repeatedly in a doallto realize the lazy list immediatly. This way you don’t get the error when you don’t use the list.

(with-in-str "..# .#. #.."
  (clojure.string/split (read-line) #" "))
;; => ["..#" ".#." "#.."]

The second argument to split is a regex. That’s one of the special syntax for # :wink:

Currently, we have:

(let [token (clojure.string/split (read-line) #" ")]
    (loop [i 3]
        (when (>= i 0)
            (let [row (nth token i)]
                (recur (dec i)))))

Though that was the only way I found, I was unsure this way was how a Clojure coder would write.

You don’t need a loop. (clojure.string/split (read-line) #" ") already does everything you want.

The code I posted is a complete example that you can paste in a REPL and execute.

The with-in-str is only there to put your example string into *in*.

(clojure.string/split (read-line) #" ") then reads the line from *in*, splits it with the regex #" " and returns a vector with the three strings you would expect.

That vector then gets returned from with-in-str, because it was the value of the last expression in the context of with-in-str. Then it gets printed to the REPL as ["..#" ".#." "#.."], because it was (again) the value of the last expression in the context of the REPL.

I just added ;; => to make clear that it is the output you see on the REPL.

Your code should be just:

(let [tokens (clojure.string/split (read-line) #" ")]
  ;; do something with tokens here
  )

I’ll discuss about it with the team, but I think we must display the variable ‘row’ in the template, so that it is easier to understand a problem that describe this variable.
One solution might be to add a “s” after the variable name (‘row’ here) and write:

(let [rows (clojure.string/split (read-line) #" ")]

Another one would be to write the variable: ‘allRow’ or ‘all_row’.

I get the impression you didn’t see my other post. I answered in two seperate posts because I thought that question was unrelated. After all, the input for Vox Codei looks different (linebreaks instead of spaces).