Arc Forumnew | comments | leaders | submit | thaddeus's commentslogin

When it comes to running news I think there's only one reference to "rm" in the "load-items" function of news.arc. It removes all ".tmp" files if any are hanging around. Since load items only happens on initialization, you can just remove that line of code. You could do the same thing using whatever means you use to load the app (i.e. manually if you want or an OS script would be better).

Also the other file-operation changes that you will need to make are:

-- In ac.scm

    1. add at the top:
    (require (lib "file.ss"))

    2. add at the bottom near the other xdef's:

    (xdef 'make-directory make-directory)
    (xdef 'make-directory* make-directory*)

 -- In arc.arc change these functions to: 

    (def mkdir (path (o parents))
         (if (is parents nil)
             (make-directory path)
             (make-directory* path)))

    (def ensure-dir (path)
        (unless (dir-exists path)
             (mkdir path t)))
You could probably look up the rm operation within file.ss and add it too.

The only other one fix I think you might need to make would be to the the shash function in app.arc, which I believe is unixy.

It's been a long time since I looked so there could be other things too.

-----

4 points by thaddeus 4847 days ago | link | parent | on: What Level Programmer Are You?

I had a hard time figuring out where I would fit in simply because I started with FP which starts at Level 9. And as for Level 10... well even though I have an interest in language design I really have no interest in designing a language (I like reading your guys's stuff, but I don't think I would want to do that myself).

So I suggest all programmers start at level 9 by starting in ARC. :)

-----

3 points by kinleyd 4847 days ago | link

Heh. And that reminds me - perhaps I'm not at lowly Level 5. I am after all, buried in Arc. :)

-----

1 point by thaddeus 4850 days ago | link | parent | on: Semi-Arc on Android

I admit, it's pretty cool, but I have wonder what it is you're planning to do with it that would make you run around in your underpants scaring your girlfriend... Lol... So can you fill us in on your plans or is it a hush hush world domination kinda thing?

[edit]

I am also asking to get people brainstorming on the possibilities, for when I sat down to think about what I could do with it I came up with nothing... So I think I'm lacking creativity or inspiration this week!

-----

1 point by akkartik 4850 days ago | link

Lol.

I was reminded of http://ycombinator.com/rfs5.html.

At least part of the excitement was in the fact that I didn't have to go through an 'app marketplace'. When everything about modern devices seems to involve jumping through endless hoops, it was a relief to have a nice experience.

Sometimes you have to use it for a while, and wait for ideas to form..

-----

3 points by thaddeus 4857 days ago | link | parent | on: Bay Area Lisp meetup

No lisp meet ups ever occur in Canada! - ugh :( And In all likelihood I'm probably like one of 5 people in Canada who both uses lisp and enjoys it. grumble, grumble...

Plus, while I'm ranting, it really kinda sux not having local lispers around to drink beer with :). Oh well.... after the fifth pint we're all lispers anyways.

-----

2 points by thaddeus 4882 days ago | link | parent | on: Best way to implement a HN themed site?

> Arc's news.arc doesn't have OpenID support

As an FYI aw (aka CatDancer) once provided code for arc/OpenID support. -> http://arclanguage.org/item?id=3333. Link is no longer valid and aws currently published pages[1] don't appear to contain the code. I'm sure if someone needed it they could contact him and he would be willing to help[2].

[1] http://sites.google.com/site/arclanguagewiki/ http://awwx.posterous.com/ http://awwx.ws/

[2] http://arclanguage.org/user?id=aw

-----

1 point by rocketnia 4881 days ago | link

I had that thread as a phantom in the back of my mind, but thanks for seeking it out.

Link rot's pretty bad around here, I guess. XD Maybe we oughta have an Arc-archive effort. ^_^;

-----

3 points by thaddeus 4907 days ago | link | parent | on: How do you make radiobuttons?

Radio buttons need the 'checked' attribute to set the initial selection.

See: http://www.w3schools.com/tags/att_input_checked.asp

Mulitple radio buttons having the same name will act as a group.

See: http://www.w3schools.com/jsref/dom_obj_radio.asp

In arc, the requested attribute will reflect the currently selected radio button for the group.

Also, note that arc's gentag doesn't handle the 'checked' attribute. So you you'll need to add:

  (attribute input      checked        opstring)
into html.arc. Just put it in with the others.

Then change your code:

  (def radio (n v (o c nil))
    (gentag input type 'radio name n value v checked c))
Results:

  arc> (radio "rdgp" 1)
  <input type=radio name="rdgp" value="1">

  arc> (radio "rdgp" 2 "checked")
  <input type=radio name="rdgp" value="2" checked="checked">
Optionally, instead of extending attributes one at a time, you can write a more generic gentag macro to handle anything you throw at it. And I'm pretty sure if you did a Google search on the arc forum you might even find it's already done.

-----

2 points by thaddeus 4913 days ago | link | parent | on: Nsv does not work.

These ".DS_Store" files are system generated by your mac computer (I think it's used to index files for spotlight searches). The file is also hidden.

Arc, however, does not filter system files - it just looks in the directory, finds the list of all files and tries to load them... and of course the news.arc tries to convert all the file names into integer keys (when loading into a table), but ".DS_Store" can not be coerced to an int, so instead you get that error.

You can fix this one of two ways. You can hack the OS to stop auto generating these files or you can change the code that gets the list of files and filter out that system file.

-----

2 points by akkartik 4913 days ago | link

Alternatively run arc as follows:

  $ rm arc/news/*/.DS_Store; mzscheme -f as.scm
It should keep you going for now.

Where are you getting arc from? There are updated resources at http://sites.google.com/site/arclanguagewiki.

-----

1 point by juanito 4899 days ago | link

I am working with MzScheme v372 and Arc3. Thank you!

-----

1 point by akkartik 4898 days ago | link

Cool. If you switch to racket and arc3.1 I think we'll be more on the same page. It should be an easy process; let me know if you have issues.

-----


  > Where is the database, how are entries being stored?
  > How does HN (Hacker News) handle the huge load and   
  promptly behave as expected, even though Arc wasn't   
  designed for speed?
All HN data is stored in text files and 90% of HN requested records (i.e. posts and comments) are held in memory for adequate performance. Also note that because 90% users only care about the top few pages of news, HN can get away with it. The remaining older items only get loaded into memory upon request, which isn't often, and they get dropped from memory over time.

Note that HN doesn't allow you modify records after a certain time frame and this gives HN the luxury to not support writes to older content and gives the users less incentive to go back to older items, lessening the need to access older data.

I believe the majority of applications many of us would need to write do not fit well into the HN model. So you'll likely discover arc has limitations given it was designed, largely, around HN.

-----

2 points by thaddeus 4939 days ago | link | parent | on: Arc noob

Already done!

http://arclanguage.org/rss

-----

1 point by vu3rdd 4938 days ago | link

Great! Thanks.

-----


I, personally, like yours better, but I don't really use best.

Note, though, that you're changing the behavior of the function in two ways:

1. nil is not returned when passed an empty list. I notice arc code does this often with the expectation that when composing your functions you may iterate though many lists to assemble them. So assembling with empty lists will break with your new function:

  old > (best > '())
  nil

  new> (best > '())
  Error: "procedure  best2: expects 2 arguments, given 0"
2. arc's current best return the first item of the two when the compare function fails, where with yours it's the opposite, and if none of them pass, arc's current one will return the first item, yours will return the last.

  old > (best (fn (x y)(> (+ x y) 10)) '(3 2 2 1 1 1))
  3

  new > (best (fn (x y)(> (+ x y) 10)) '(3 2 2 1 1 1))
  1
I'm not sure if this matters, since I have not checked where & what 'best' is actually used for. I'm just noting that you're changing the behavior quite a bit.

-----

1 point by akkartik 4958 days ago | link

#2 is the old foldl vs foldr conundrum[1]: http://en.wikipedia.org/wiki/Fold_%28higher-order_function%2.... I think it's irrelevant which fold you use for best because the answer will only diverge if all the elements in the list are 'equal' according to the metric. Your example is like that.

Then again, you could argue that the original behavior is more 'stable': it's like sorting the list and taking the first element.

[1] Rich Hickey recently called fold/reduce 'complex' because of the variants. http://arclanguage.org/item?id=15269; I didn't expect to be able to cite it so soon :)

-----

2 points by rocketnia 4956 days ago | link

"I think it's irrelevant which fold you use for best because the answer will only diverge if all the elements in the list are 'equal' according to the metric."

If anyone called 'best on an infinite list, I'd expect it to diverge regardless of how it was implemented. You never know if something's the maximal/minimal element unless you've checked all the others.

(If 'best operated on heaps or something, then you might be able to say "this potentially infinite substructure has no better candidates" because the heap structure makes guarantees like that.)

Anyway, #2 is still irrelevant because it's trivial to fix:

   (def best (f seq)
     (reduce (fn (a x)
  -            (if (f a x) a x))
  +            (if (f x a) x a))
             seq))
Even if we used 'rreduce instead of 'reduce here, this fix would still be necessary (if we consider #2 important to fix at all).

Here's a fix for #1 as well, along with a return to the original variable names:

   (def best (f seq)
     (when seq
       (reduce (fn (wins elt)
                 (if (f elt wins) elt wins))
               seq)))
This still leaves one inconsistency with the original: This version behaves more intuitively in the presence of continuations, because it doesn't use mutation.

-----

2 points by rocketnia 4956 days ago | link

"If anyone called 'best on an infinite list, I'd expect it to diverge regardless of how it was implemented."

Oops, I didn't consider that 'best in Arc actually does operate on a data structure that has enough information to tell you whether an infinite substructure can contain a better candidate: If any tail of the list is 'is to one of the tails you've already encountered, its length is infinite but it certainly has no better candidates (since you've already seen them all). All infinite lists in Arc have tails that contain themselves as tails, so it's possible to make an Arc 'best that terminates on any infinite list.

-----

1 point by rocketnia 4956 days ago | link

"Rich Hickey recently called fold/reduce 'complex' because of the variants."

Because of the variants? The only mention of fold I found was this one:

Rich Hickey (at 30:33): "Imperative loops--fold, even, which seems kinda higher-level? Still has some implications that tie two things together... whereas set functions are simple."

I thought he was referring to the way the calls to the folded function are all lined up in a dependency chain, just like they'd be lined up if you were using an iterative loop.

  (state before the iteration, input to this iteration)
    -> state after the iteration
To illustrate, in a procedural language, it's easy and efficient to define a left fold as an iterative loop:

  (def foldl (first rest func)
    (ret result first
      (each elem rest
        (zap func result elem))))
This is the same as the 'best change we're talking about. But since Arc's continuations make more sense when there's no mutation going on, I recommend not implementing 'foldl and 'best this way.

With "set functions," you can determine certain properties about the result if you know some subsets' results:

- The result of (some odd (join '(17) foo)) is t, because (some odd '(17)) is t.

- The result of (keep odd (join '(17) foo)) has at least the element 17 in it, because (keep odd '(17)) has that element in it.

Rich Hickey's main point is that these "simple to reason about" properties help humans. But they also mean that if we know enough about these function calls statically (which we never do, in Arc), we might be able to turn them into constants without knowing the value of 'foo, or at least we might be able to parallelize them. These set functions may be implemented as special cases of fold, but fold doesn't have the same reasoning potential in the general case.

Instead of saying "you can compile it better," Rich Hickey would probably spin this as "you can leave the 'how' up to the language implementor."

-----

1 point by akkartik 4956 days ago | link

"The only mention of fold I found was.. 30:33"

Look around minute 40. He says they complect what to compute and how to compute it, which I took to mean the need to specify foldl/foldr.

The difference with your version is mostly just phrasing, though.

-----

1 point by rocketnia 4956 days ago | link

Ah, here we go:

"Loops and fold! Loops are pretty obviously complecting what you're doing and how to do it. Fold is a little bit more subtle, 'cause it seems like this nice 'somebody else is taking care of it,' but it does have this implication about the order of things. This left-to-right bit."

I can see how you'd get that. I think our interpretations are related. As far as how they're related goes...

The underlying issue may be that introducing non-commutativity makes an operation more cumbersome when used with sets, and introducing non-associativity makes it even worse.

- Commutative and associative: If you apply '* or 'max pairwise to a set, you can only get one result. (It's possible to implement 'some this way, and a 'keep that returns an unordered bag.)

- Associative: If you apply 'compose or 'join pairwise to a set, you can get many results, but you can choose between them by putting the items in a list. (It's possible to implement 'keep this way.)

- Commutative: If you apply XOR pairwise to a set, you can get many results, but you can choose between them by placing the items on the leaves of a rooted binary tree.

- Neither: If you apply 'cons pairwise to a set, you can get many results, but you can choose between them by placing them on the leaves of a rooted binary tree with a distinction between left children and right children.

Both 'foldl and 'foldr are specific enough to be deterministic when they're used with non-associative, non-commutative operations like 'cons. The fact that they're so specific is why there isn't just one 'fold.

-----

1 point by rocketnia 4956 days ago | link

Oops, XOR may be commutative, but it's also associative. XD Here's something that isn't:

  arc> (isnt 'zip (isnt 'nada 'nil))
  t
  arc> (isnt (isnt 'zip 'nada) 'nil)
  nil
Since 'isnt over the set { t, nil } is XOR, I jumped to conclusions.

Here's another:

  arc> (is 'zip (is 'nada 'nil))
  nil
  arc> (is (is 'zip 'nada) 'nil)
  t
I was intentionally avoiding 'is as an example, since it has an intuitive meaning when applied to a set (IMO), which is different from applying it piecewise.

-----

2 points by thaddeus 4958 days ago | link

re: [1], ah yes, ... he also deemed 'inconsistency', as 'complect' too. So, at the very least, arc code should be consistent if not simple. :) - lol.

-----

1 point by rocketnia 4956 days ago | link

He wasn't talking about "consistency" in the sense of the principle of least astonishment.

If two parts of the program observe the system at the same time but see different states, that's called inconsistency. Consistency is difficult to achieve in a distributed program, thanks to the fact that "observation" isn't necessarily instantaneous or reliable. Per the CAP theorem (http://en.wikipedia.org/wiki/CAP_theorem), to achieve full consistency in a distributed program you have to sacrifice availability or partition tolerance. These three properties are inherently complected.

A popular sacrifice is to only guarantee a sort of eventual consistency (http://en.wikipedia.org/wiki/Eventual_consistency). That is, for any given state of the system, given enough time to communicate, every part of the system will catch up to that state. It's like saying that a garbage-collected program eventually releases memory.

-----

1 point by thaddeus 4956 days ago | link

I think you're over analyzing. Although "consistency" in the general sense, was not the only thing he was talking about... it was obvious he was including that, he even dumbed it down to that point within his presentation.

Things that are consistent are simpler than things that are not.

And I do feel that way about arc code. Having half your functions accounting for nil, while ignoring it for the other half, would make coding in arc less simple, than making sure they all accounted for it (as a general statement without debating the specifics).

-----

1 point by rocketnia 4956 days ago | link

Sure, I agree he was talking about that kind of consistency too. I spoke too matter-of-factly for once. ^_^

I was more specifically referring to the part at 31:17 where he had Inconsistency vs. Consistency on the slide and he explained the complexity as "taking a set of things that stand apart and trying to think of them all at the same time." He finished that line of thought with "And anybody who's tried to use a system that's eventually consistent knows that."

(Note that he's talking about eventual consistency as being on the "Inconsistency" side, which I guess is because an eventually consistent system is often on the way to consistency rather than being there.)

-----

1 point by dpkendal 4956 days ago | link

The first one is clearly in issue. I propose also to replace reduce with this (happily, tail-recursive) version:

    (def reduce (f xs)
      ((rfn rdc (a s)
        (if (no s)
          a
          (rdc (f a (car s)) (cdr s)))) (car xs) (cdr xs)))
which avoids this problem by returning nil when `xs` is nil.

However, I would consider the second issue to be merely incidental. It is still a correct result.

-----

2 points by thaddeus 4956 days ago | link

I wouldn't assume something is incidental unless the purpose has been researched. And, I believe, its correctness can only be determined by its intended use... Which is why I was kinda suggesting someone check where and why it's actually used.

As a guess, 'best' is probably used for http://arclanguage.org/best in the news.arc code. In which case it's probably not an issue... ?

At any rate, references should probably be checked? Or maybe, instead, news.arc code should be dropped from anarki? Could it be that supporting news.arc only stifles arc's development?

-----

2 points by rocketnia 4955 days ago | link

I think supporting anything stifles development. It's a contradiction I just try to accept. :-p

I don't see the purpose of 'best. I don't see a bigger purpose in most of Arc. If what Arc gives me isn't what I need, I reinvent it.

(In fact, I think if we try to keep working on the same language, rather than tearing it down and reinventing it, we're worrying about at least some kind of "support" and stifling our development. But too much tearing down can be destructive too, of course. :-p I appreciate that you're applying a scientific-ish mindset to this.)

There are a few ways to cut through this Arc ennui:

- If Arc gives me tools I can use to reinvent things, those tools are extra-relevant, since even if I don't like them I'll use them on my way to replacing them. This is not something 'best does for me.

- Sometimes we may want everyone in the language community to use the same variant of something, so that the tools we build around that thing can work together. Are we trying to optimize 'best in the compiler/runtime? Nope. Do people often extend 'best with extra capabilities? Nope. Even if these things were true, are we even having an issue with people reinventing 'best all the time? Nope, I don't think so.

- Do I still kinda like to discuss it? Yep. :-p

-----

3 points by thaddeus 4955 days ago | link

I agree with everything you're saying... and, also, in thinking about it further, I believe that having namespaces as a first class feature is the best way to solve this kinda problem.

For example, in Clojure, I can just build my project by excluding the function in question and replace it with my version. Anyone else that wants to use Clojure doesn't need to worry about another persons great idea.

; example

  (ns a-project.core
    (:refer-clojure :exclude (best))
    (:gen-class))
  
  (defn best []
    ...)
And anyone else wanting to use my library and/or only use my version can do so, simply:

  (ns your-project.core
    (:refer-clojure :exclude (best))
    (:use [a-project :only (best)])
    (:gen-class))
   
   (defn do-my-stuff []
    (best ....))
And I can't even remember now - did anarki get namespaces? I know there were some implementations, I just don't know if it made its way into anarki.

I also believe namespaces would promote the sharing of libraries, which arc also suffers from.

-----

1 point by rocketnia 4956 days ago | link

I think it's cleaner to define 'reduce in terms of 'foldl:

  (def reduce (func xs)
    (whenlet (x . xs) xs
      (foldl func x xs)))
But I don't even really want 'reduce. If the function is '+, an empty list should give 0. If the function is '*, an empty list should give 1. Instead of trying to divine this value from nowhere, I think it makes more sense to pass the base case manually, as with 'foldl.

Alternatively we could have this...

  (def reduce (func xs)
    (iflet (x . xs) xs
      (foldl func x xs)
      (func)))
...but if the function is set up to take different numbers of arguments, we probably should have done (apply func xs) in the first place.

-----

More