Arc Forumnew | comments | leaders | submitlogin
Pluralize no longer supports lists
1 point by akkartik 1335 days ago | 15 comments
https://github.com/arclanguage/anarki/commit/d9784133

I've also added an old suggestion by zck: https://github.com/arclanguage/anarki/commit/8560dd1482



2 points by rocketnia 1335 days ago | link

Not to reward you with more work to do, but how about updating the docs? XD

https://github.com/arclanguage/anarki/blob/master/help/strin...

    pluralize
    " Returns `str' pluralized. If `n' is 1 or a list of length 1, `str' is
      returned unchanged; otherwise an `s' is appended.
      See also [[plural]] "
  
    plural
    " Returns a string \"<n> <x>\" representing `n' of `x' in english, pluralizing
      `x' if necessary.
      See also [[pluralize]] "
https://github.com/arclanguage/anarki/blob/master/extras/arc...

  (def pluralize "n str" "Returns str pluralized; if n is 1 or a list of length 1, str is returned unchanged; otherwise an 's' is appended. Renamed from plural in arc3."
  (tests (pluralize 2 "fox") (pluralize '() "fish")))
  (def plural "n str" "Returns n and str pluralized. New in arc3."
  (tests (plural 2 "fox") (plural '() "fish")))

-----

1 point by akkartik 1335 days ago | link

Yes, the docs are on my list :) Need to reacquaint myself with how to update them..

Edit: oh, you mean those help files! I always forget those exist.. I was thinking about kens's arc reference (http://arclanguage.github.io/ref) which shader prodded us earlier about: http://arclanguage.org/item?id=18536.

Do we still care about the help dir?

-----

2 points by rocketnia 1335 days ago | link

"oh, you mean those help files!"

Well, I linked to both. :)

--

"Do we still care about the help dir?"

It would be nice if both of those help resources I linked to could share the same codebase. They seem to share a lot of content already.

Er, actually I think kens's files might be generated using a script that scrapes those help files. ...Nope, I can't find that script, if it exists.

-----

1 point by akkartik 1335 days ago | link

OMG, I just realized how that help dir is used:

  arc> (help do)
  [mac] (do . args)
   Evaluates each expression in sequence and returns the result of the
      last expression.
      See also [[do1]] [[after]] 
This is awesome. Yes, worth updating. Let me think about how to sync it with the reference. (I'd also forgotten that the reference is generated from anarki. Is that still true, or is this copy redundant? Need to check..)

-----

2 points by rocketnia 1335 days ago | link

Sorry, I think I was mistaken. If the hypertext reference is generated from docstrings at all, I don't see how. Even if there were a tool, it would require some manual work afterward to place the definitions into appropriate categories.

-----

2 points by akkartik 1324 days ago | link

I've updated the docs. I've also taken out the help/ dir entirely and inlined all the docstrings into arc.arc and elsewhere.

I'm still unsure how to organize the arcfn reference guide at http://arclanguage.github.io/ref so that we remember to update it when we make changes, and so it's convenient to update the website. Another complication is that the arclanguage account contains multiple dialects of arc with subtle differences, and the current organization of documentation is misleadingly monolithic. Any suggestions to fix this most appreciated. (We discussed this previously a year ago: http://www.arclanguage.org/item?id=17774)

-----

4 points by akkartik 1322 days ago | link

Ok, I've taken a stab at a minimal-effort reorg of http://arclanguage.github.io. Before: http://i.imgur.com/hCpkFyj.png. After: http://i.imgur.com/KvwrEg9.png. It's more clear now that tryarc and /ref/ are for arc 3.1. Anarki is currently just more capable at the commandline.

-----

2 points by evanrmurphy 1322 days ago | link

Makes the Arc 3.1 vs. Anarki distinction much clearer to a new visitor. Nice job, akkartik.

-----

2 points by thaddeus 1323 days ago | link

Something like marginalia[1] might prove to be better than the arcfn docs. Not only because the docs would be fully integrated with the source code, but because it would also solve the multiple dialects problem. i.e. If some given code can be tagged with a dialect name then automation could also apply a dialect filter.

Of course this would probably be quite a bit of an undertaking.

1.http://gdeer81.github.io/marginalia/ & https://github.com/gdeer81/marginalia

-----

2 points by akkartik 1323 days ago | link

The crux is colocating the rendered docs online with the repo. Would marginalia help us use github's hosting with github pages, managing branches, etc? If it does I think I'd be willing to go on a significant undertaking.

-----

2 points by thaddeus 1323 days ago | link

Marginalia is clojure specific so I expect it will not help other than to provide ideas.

To create an arc equivalent you probably need build an arc library which provides some code inspection/dissection capabilities and ideally also be able to attach metadata to any given function or macro. With such a library you then build a script to auto generate the docs.

As for GitHub syncing; well no, I'm guessing users would need to trigger the script and then check in the updated docs.

This is still better for a few reasons...1. developers can generate docs, locally, that are in sync with the code base they are actually using (checked out or branched). 2. Even if the online docs gets out of sync for a while you're still only a script trigger away for updating all outstanding changes.

The alternative is what you just went through; having someone remind you to do the work manually as an after-thought, which I've only seen happen once.

-----

2 points by rocketnia 1335 days ago | link

It's funny to see you make this change to 'pluralize, 'cause I was thinking of exactly the reverse change for everything else.

In the language(s) I'm working on, the number type has mainly been a way to represent list indexes and lengths. List processing depends on integer processing, or so I thought. The other day I realized I could just use lists instead.

  ; Scheme-ish code
  
  > (list-ref '(a b c) '())
  a
  
  > (list-ref '(a b c) '(z))
  b
  
  > (list-ref '(a b c) '(y z))
  c
  
  > (len '(a b c))
  (() () ())  ; or even (a b c)
This unary encoding won't be efficient for big numbers, but these aren't very big numbers. They're no bigger than other cons lists that I already have in memory, and they might even share the same structure.

So I'm thinking that even if I do support other number types, I'll very rarely need to use them for counting first-class objects. They'll mostly be for counting pixels, milliseconds, etc.

-----

2 points by zck 1334 days ago | link

Huh, this is similar to Church numerals: https://en.wikipedia.org/wiki/Church_encoding

What was the reason you decided to do it this way? It seems more complicated to work with.

-----

2 points by rocketnia 1334 days ago | link

"What was the reason you decided to do it this way? It seems more complicated to work with."

In my designs, I don't just want to make things that are easy for casual consumers. I want to make things people can consume, understand, talk about, implement, upgrade, deprecate, and so on. These are things users do, even if they're not all formal uses of the interface.

I hardly need number types most of the time. If I add them to my language(s), they might just be dead weight that makes the language design more exhausting to talk about and more work to implement.

Still, sometimes I want bigints, or at least numbers big enough to measure time intervals and pixels. I don't think any one notion of "number" will satisfy everyone, so I like the idea of putting numbers in a separate module of their own, where their complexity will have a limited effect on the rest of the language design.

---

"Huh, this is similar to Church numerals"

I'm influenced by dependently typed languages (e.g. Agda, Twelf, Idris) which tend to use a unary encoding of natural numbers in most of their toy examples:

  data Nat = Zero | Succ Nat
To be fair, I think they only do this when efficiency isn't as important as the simplicity of the implementation. In toy examples, implementation simplicity is pretty important. :)

A binary encoding might use a technique like this:

  data OneOrMore = One | Double OneOrMore | DoublePlusOne OneOrMore
  data Int = Negative OneOrMore | Zero | Positive OneOrMore
Or like this:

  data Bool = False | True
  data List a = Nil | Cons a (List a)
  data Int = Negative (List Bool) | Zero | Positive (List Bool)
I get the impression these languages go to the trouble to represent these user-defined binary types as efficient bit strings, at least some of the time. I could be making that up, though.

For what I'm talking about, I don't have the excuse of an optimization-friendly type system. :) I'm just talking about dynamically typed cons cells, but I still think it could be a nifty simplification.

-----

2 points by rocketnia 1334 days ago | link

  data Nat = Zero | Succ Nat
I don't think this itself would be called Church numerals, but it's related. The Church encoding takes an ADT definition like this one and looks at it as a polymorphic type. Originally we have two constructors for Nat whose types are as follows:

  Zero : Nat
  Succ : (Nat -> Nat)
These two constructors are all you need to build whatever natural number you want:

  buildMyNat : Nat -> (Nat -> Nat) -> Nat
  buildMyNat zero succ = succ (succ (succ zero)))
We could make this function more general by abstracting it over any type, not just Nat:

  buildMyNat : a -> (a -> a) -> a
This type (a -> (a -> a) -> a) is the type of a Church numeral.

While it's more general in this way, I think sometimes it's a bit less powerful. Dependently typed languages often provide induction and recursion support for ADT definitions, but I think they can't generally do that for Church-encoded types. (I could be wrong.)

For something more interesting, we can go through the same process to build a Church encoding for my binary integer example:

  data OneOrMore = One | Double OneOrMore | DoublePlusOne OneOrMore
  data Int = Negative OneOrMore | Zero | Positive OneOrMore
  
  buildMyInt :
    OneOrMore ->                  -- One
    (OneOrMore -> OneOrMore) ->   -- Double
    (OneOrMore -> OneOrMore) ->   -- DoublePlusOne
    (OneOrMore -> Int) ->         -- Negative
    Int ->                        -- Zero
    (OneOrMore -> Int) ->         -- Positive
      Int
  
  buildMyInt :
    a ->          -- One
    (a -> a) ->   -- Double
    (a -> a) ->   -- DoublePlusOne
    (a -> b) ->   -- Negative
    b ->          -- Zero
    (a -> b) ->   -- Positive
      b

-----