Fork me on GitHub
#off-topic
<
2022-05-08
>
borkdude09:05:23

Any opinions on fully collapsed docs like this: โ€ข https://github.com/babashka/sci/blob/master/API.md or just everything fully expanded without collapse option, like this: โ€ข https://github.com/babashka/process/blob/master/API.md Note that you can use the menu on the top left to navigate as well.

borkdude09:05:43

๐Ÿงต

j abns09:05:10

+1 without collapse. Easier to scan the page when looking for something

โž• 3
p-himik09:05:09

Same. And Ctrl+F works only with an expanded version.

โœ… 2
borkdude09:05:19

It's also possible to only collapse namespaces and not the vars. But I assume you would still prefer to have everything expanded, right?

p-himik10:05:31

Yep. :) Keeping it neat but also easily accessible isn't really possible with a plain MD viewer. But an external viewer might be used, like cljdoc, I suppose.

j abns10:05:24

Expanded. Scrolling is easier than clicking and easier to stay in the flow

j abns10:05:03

The less clicks between the user and the content the better

โž• 2
adi10:05:07

Everything expanded + Table of Contents (deep-linked items, with depth h1, h2, h3)

p-himik10:05:36

Oh, I guess that would work with a plain MD viewer as well. But you'd have to create the ToC manually and keep it up to date.

borkdude10:05:57

Creating a TOC isn't a problem :)

๐Ÿ‘ 2
adi10:05:21

I consider a ToC to be basic hygiene in long-enough documents (anything that scrolls beyond about 2 screenfuls of a typical FHD 14" screen).

adi10:05:43

because it immediately suggests the flow of the doc, summarises key topics, and provides hints to ctrl-f terms.

jjttjj15:05:13

I agree about the toc. I'm pretty neutral on expand vs not but definitely yearn for a toc/listing of all var names at the top when looking at these

p-himik18:05:54

Looks pretty good! But I'd probably replace those : - with just - or just : . Otherwise, it's a bit noisy, at least for me.

borkdude18:05:15

oh that was a typo

adi18:05:43

Noice! It's doubling up as an Index too!

p-himik18:05:19

Oh, probably another typo - "SCI var that represents SCI's" should be "SCI var that represents Clojure's". Right?

p-himik18:05:34

And *x* becomes x.

borkdude18:05:21

yeah, those are issues in the docstrings themselves, not with quickdoc, I'll fix them eventually. The "SCI var that represent's SCI's ..." is not a typo, it is truly the interpreter's version of x, which is an analog to Clojure's x.

borkdude18:05:25

I realize I might not have explained properly what quickdoc is. https://github.com/borkdude/quickdoc

p-himik18:05:25

Ah, alright. :) But I think the issue with *x* is the issue with the MD format itself or quickdoc not escaping *, no?

borkdude18:05:22

it's an issue in the docstring, the docstring should probably use markdown syntax

borkdude18:05:47

at least, that's what I'm going to do going forward with this, I think

borkdude18:05:41

or do you have a better / alternative idea?

p-himik18:05:56

If that's still an open question, it feels like escaping all * might get quite tedious due to their amount. And it would be easy to just miss a few. Maybe a somewhat customized version of MD that doesn't interpret formatting within backticks?

borkdude18:05:22

Some of these preferences could be configurable. E.g automatically converting earmuffed var names to *foo*

borkdude18:05:47

I probably never want to use italics in docstrings, so that should probably work

p-himik18:05:54

Sounds like it!

borkdude18:05:59

we could even automatically markup as code any words that occur in the arglists too :P

p-himik18:05:35

Mm, not sure about this one - that would require paying attention to not naming the args with plain English words. I myself, even though I don't use any doc generators, prefer to just put backticks around any code, including regular mentions of args.

borkdude18:05:57

including earmuffed vars right?

borkdude18:05:23

As in:

(defn foo "something blabla `*dude*`" [])

borkdude18:05:03

I agree btw, that was the first thought I had too, there are cases when you just want to use the word

p-himik18:05:32

> including earmuffed vars right? Yep!

borkdude18:05:38

That's what I'm going to do too, so for me personally there would be no need to auto-markdowning earmuffed vars

p-himik18:05:04

My internal text parser demands it at this point. :) Sometimes it takes noticeable effort to get through some docstring in clojure/core just because it uses the same word for both code and non-code. Nice!

didibus21:05:42

I do the same, backtick anything that refers to "code"

๐Ÿ‘ 1
souenzzo13:05:19

How would you implement this algorithm in clojure?

for i = 1 to n do
  for j = 1 to n do
    if A[i] < A[j] then
      swap A[i] and A[j]
https://twitter.com/chordbug/status/1523016806348304385

๐Ÿ‘ 1
p-himik13:05:30

Assuming A is a mutable data structure, it'd be a very similar code, with two loops. If A is something immutable, just make it transient, sort, then make persistent.

๐Ÿ‘ 2
souenzzo14:05:08

Something like this:

(let [a (transient [3 1 2])]
  (doseq [i (range (count a))]
    (doseq [j (range (count a))]
      (when (< (get a i)
              (get a j))
        (assoc! a
          i (get a j)
          j (get a i)))))
  (persistent! a))
This solution is wrong because we should always use the return of assoc! in the next assoc! Why is so hard to write this algorithm in clojure?

p-himik14:05:44

doseq + range can be replaced with dotimes. :) Note also that you have to use loops because you have to use the result of assoc! - you can't ignore it. Never mind, you mentioned that and I'm blind.

p-himik14:05:38

> Why is so hard to write this algorithm in clojure? It's not hard if you use loop?..

souenzzo14:05:37

Another round:

(let [*A (atom (transient (shuffle (range 20))))
      size (count @*A)]
  (dotimes [i size]
    (dotimes [j size]
      (let [a @*A]
        (when (< (get a i)
                (get a j))
          (swap! *A assoc!
            i (get a j)
            j (get a i))))))
  (persistent! @*A))

p-himik14:05:27

Why do you not want to use loops?

souenzzo14:05:33

i'm trying to solve with loop/recur.

souenzzo14:05:35

Something like this:

(let [A [3 1 2]
      idxes (range (count A))]
  (loop [[i & is] idxes
         a A]
    (if (seq is)
      (recur is (loop [[j & js] idxes
                       a a]
                  (if (seq js)
                    (if (< (get a i)
                          (get a j))
                      (recur js (assoc a
                                  j (get a i)
                                  i (get a j)))
                      a)
                    a)))
      a)))

p-himik14:05:25

This is what I meant:

(let [A (transient (shuffle (range 20)))
      n (count A)]
  (persistent!
    (loop [i 0, A A]
      (if (< i n)
        (recur (inc i)
               (loop [j 0, A A]
                 (if (< j n)
                   (let [vi (nth A i)
                         vj (nth A j)]
                     (recur (inc j)
                            (cond-> A (< vi vj) (assoc! i vj j vi))))
                   A)))
        A))))

p-himik14:05:17

Although, at this point you can get rid of the transient step, heh. But that probably won't help the performance. On the other hand, if you care about performance even a bit, then you should 100% use some other sorting algorithm.

souenzzo14:05:33

I'm not thinking in performance or anything like this. I'm just stumble in translate this pseudocode into clojure code.

souenzzo14:05:04

I think that the best solution that I can do in clojure is

(defn my-sort
  [A]
  (let [*A (volatile! A)
        n (count A)
        flip (fn [a i j]
               (assoc a
                 i (get a j)
                 j (get a i)))]
    (dotimes [i n]                        ;; for i = 1 to n do
      (dotimes [j n]                      ;;   for j = 1 to n do
        (when (< (get @*A i) (get @*A j)) ;;     if A[i] < A[j] then
          (vswap! *A flip i j))))         ;;       swap A[i] and A[j]
    @*A))
(my-sort (shuffle (range 3)))
;
Where my challenge is "translate pseudocode into code in the most literal way"

p-himik14:05:42

The most direct translation would probably be this:

(let [v (shuffle (range 20))
      A (long-array v)
      n (count A)]
  (dotimes [i n]
    (dotimes [j n]
      (let [vi (aget A i)
            vj (aget A j)]
        (when (< vi vj)
          (aset A i vj)
          (aset A j vi)))))
  (vec A))
But it has a limit on the size of A.

๐Ÿ‘ 1
Alexis Schad14:05:04

You can use reduce:

(reduce (fn [A [i j]]
            (if (< (A i) (A j))
              (swap A i j)
              A))
          A
          (for [i (range n)
                j (range n)]
            [i j]))

๐Ÿ‘ 3
eggsyntax21:05:49

I ended up just banging on it mutably as some of the earlier attempts do. That seems pretty suitable in this case.

(defn swapper [A-orig]
  (let [A (to-array A-orig)
        n (count A-orig)]
    (dotimes [i n]
      (dotimes [j n]
        (when (< (get A i) (get A j))
          (let [i-val (aget A i)]
            (aset A i (aget A j))
            (aset A j i-val)))))
    (seq A)))

eggsyntax21:05:41

You could definitely do in more of a pure functional way, but it'd be pretty ugly ๐Ÿ˜œ I think you'd reduce and the reducing fn would end up something like (broken, I'm sure, I'm just tossing something out there)

(fn [A [i j]]
     (if (< (get A i) (get A j))
       (concat
        (take i A)
        (list (get A j))
        (take (- (Math/abs (- j i)) 2)
              (drop (inc i) A))
        (list (get A i))
        (drop j A))
       A))

p-himik21:05:31

But... why? A solution right above uses reduce with a simple function. That swap is just a single assoc.

eggsyntax21:05:59

I'm just imagining if you wanted to do something more conventionally functional, without loops. I agree yours is better & there's no good reason for the proposal I just made, I'm just playing around ๐Ÿ˜

p-himik21:05:37

Nah, not mine - from Alexis, with reduce and without any loops.

eggsyntax22:05:52

Ohhhh, I see, I didn't look closely enough at that flip fn, that's quite nice. That's doing what I was aiming at, in a far better way. ๐Ÿ˜Š

eggsyntax22:05:37

Forgot you could assoc a vector.

Alexis Schad22:05:35

Yes I was matching initial algorithm terms but (swap A i j) is just (assoc A i (A j) j (A i))

๐Ÿ‘ 1