Arc Forumnew | comments | leaders | submit | thaddeus's commentslogin
1 point by thaddeus 5951 days ago | link | parent | on: New Version of Arc

in news.arc

    (def load-items ()
      (system (+ "rm " storydir* "*.tmp"))
; errors when there are no .tmp files. not a biggie since it still goes on.

rm: .../news/story/*.tmp: No such file or directory

Still working on it but so far the newsforum only displays when I am logged in. otherwise it's blank.

-----

1 point by pg 5951 days ago | link

Yeah, I didn't try to suppress error messages because I'm curious how often it actually finds something.

When you say blank, do you mean completely blank, or just no stories? Because caching means that stories take a minute to show up to nonlogged-in users.

-----

1 point by thaddeus 5951 days ago | link

Re-installed. Works fine. I will look at further, but all is good so far. Thanks, T.

-----

2 points by thaddeus 5951 days ago | link

Ok now it's not my environment. I have made no changes just the arc3 files and mzscheme372.

* I have only 3 posts and 3 comments, if I log in as admin and keep hitting the comments link - not crazily like, but right after the page load completes - about the 10th time or so the hyperlinks change format then the whole forum get locked and goes blank.

I am using mac osx.

After about an hour I'm getting the impression the forum is glitchy. There's just a bunch of quirky behavior like the above (pages are slower to load - page painting is noticeable.... etc etc)

Not like the old arc2 forum on the same machine.

T.

-----

3 points by pg 5950 days ago | link

You're probably setting off the code that protects against overly aggressive clients. See abusive-ip in srv.arc.

Try restarting Arc and evaluating this expression

    (def abusive-ip (x) nil)
before starting up News, and see if you still have a problem.

This will show you requests that have been ignored, by ip address:

http://localhost:8080/spurned

-----

2 points by thaddeus 5950 days ago | link

LoL. And here I was thinking I was helping by doing a little bit of stress testing :)

That fixed it. T.

-----

1 point by thaddeus 5951 days ago | link

stopped; rebooted. this time without even logging in - on the 4rth time clicking the comments link - it froze up.

-----

1 point by thaddeus 5952 days ago | link | parent | on: Example: Rewriting the login code

Much nicer!

Interesting though - I do find it odd that when applying defopl to the root "||" the function doesn't return to the root after login, but rather it fowards to an 'afterward' of "y". Looks as though the code expects that you pass a string in as the afterward and will not take || as an argument.

T.

-----

2 points by thaddeus 5954 days ago | link | parent | on: Any other arc news forums out there?

Ok I've been working at finally deploying something; I am running into problems.

Here's what I have done:

    * I've set up a vps with linode; ubuntu 9.04 with apache2
    * I've made sure my domain name hits the right IP.
      (i.e. I get "It's Alive.") when I go to the domain name site.

    * I've created a user on the VPS and deployed arc.
    * I can launch arc and run the as the user.
 
    (I notice (asv 80) doesn't work: "error 32"; I am gathering this is because I am not running as root - that's fine.).
 
    * So I enable mod_proxy and added a proxypass to the apache httpd.conf file:

     ServerName mydomain.com
     ProxyPass / http://localhost:8080/

     Restarted the apache server and I get the following at mydomain:

     Internal Server Error
     The server encountered an internal error or misconfiguration and was unable to complete your request.
Any ideas ? Thanks, T.

-----

1 point by CatDancer 5954 days ago | link

Your ProxyPass command is the one I was using with Apache.

Anything in the Apache error log?

Also, are you able to get to port 8080 on the box? I.e.

  curl -v -s http://localhost:8080/

-----

1 point by thaddeus 5949 days ago | link

Ok so after getting an arc3 forum, running on linode - using proxypass I notice I am getting periodic 502 proxy errors.

Also I found this old post that claims that these timeouts are a side effect of the 'date' problem that Anarki had fixed, but in Arc3 pg fixed the date function so i am guessing this wouldn't be the issue?

http://arclanguage.org/item?id=4728 http://arclanguage.org/item?id=4714

any ideas ?

Thanks, T.

-----

1 point by CatDancer 5949 days ago | link

Anything in the Apache error log about what it doesn't like about the response it's getting from the Arc web server?

Oh and if you hit your forum directly at the 8080 (or whatever) port do you have any similar problems?

-----

1 point by thaddeus 5949 days ago | link

Good idea - I should have done that.

I am proxy passing from port80 to 3 different ports for 3 different domains (each running it's own arc server). Looks like the calls are getting mixed up.

ie. mydomain1.com, mydomain2.com, mydomain3.com

looks like mydomain1.com should be calling

    mydomain1.com/public/favicon.ico
but instead it's getting passed to mydomain2.com

File does not exist: ....mydomain2.com/public/favicon.ico

hmmm. There must be a better way to keep the pointers in order. Back to google :)

T.

-----

1 point by thaddeus 5949 days ago | link

well i think it's fixed.

I just changed:

  favicon-url*  "" to  ->  favicon-url*  "logo.gif"
I'm hazarding guess, but I think when apache can't find a file via the arc servers static directory apache attempts to find it using anyone if not all of the public directories listed in the virtual hosts.

strange, but anyway - thanks for trying to help Cat, sorry to be a pain - this was my first time installing apache, linux or doing any of this stuff :).

T.

-----

1 point by thaddeus 5954 days ago | link

Thanks Cat,

I did manage to figured it out... I had to add the proxy_http module. T.

-----

1 point by thaddeus 5955 days ago | link | parent | on: Any other arc news forums out there?

Nice. Thanks. I think that's Russian correct? (pardon if I got it wrong).

I'm just curious. Although I don't use hacker news much (can't relate to the topics as much) - I can see how the layout and usage is much better than most sites I visit. And I can see a mutlitude of uses for it - not just news. So I am just surprised I haven't seen more of them. I was thinking about starting one up for my industry peers (not the hackers).

Just wanted to see what other members experiences were. T.

-----

1 point by zhtw 5955 days ago | link

> Nice. Thanks. I think that's Russian correct?

Yep.

And I'm too using it not because it's written in Arc, but because it just looks good.

-----


I like mz. It's short and clear to me.

-----


Works for me. I am reading onlisp while I learn arc, and although I don't fully understand half the code in the book the concepts are what's important.

As an example; I think it's like chapter 25 where pg describes how one can do object oriented programming in lisp. I was able to look at his code a see how his functions became fewer more readable lines in arc, but more over I am able to start working on oo concepts even though arc doesn't have a direct map to class and superclass functions.

T.

-----

2 points by zhtw 5958 days ago | link

The really good idea would be to rewrite all the code from the book in Arc. I love the book and I don't know Common Lisp. The book would be much clearer with examples written in Arc. For example generalized variables: I didn't even read examples from the book, I read the Arc source instead.

-----

2 points by anarcer 5958 days ago | link

Nice idea rewriting all book in Arc: OnArc!

-----


I imagine a table as I would like to perform all the normal table operations on it like:

    (keys mything*) 
     
     or (mything* 'this)
     etc etc...
I initially thought a function like (point mything* (parent* thing*)) would be ideal, but then realized it would also probably require the 'let' usage to work otherwise the scope would be a problem.

T.

-----

1 point by CatDancer 5958 days ago | link

So table thing* is a key in the table parent*?

Could you either describe what you want to accomplish or else give some working code examples that you'd like to see simplified? I'm having trouble figuring out what you want your code to do from these fragments.

-----

1 point by thaddeus 5958 days ago | link

    -> So table thing* is a key in the table parent*?

    Yes.
Ok so this is probably exposing how newbish I really am, but please bear with me.... I tried to create an example that better describes what I am thinking.

Data set up:

    (= app* (table))
    (fill-table app* (list "yardwork" 
	                       (obj budget*   (table)
                                forecast* (table))))
    (fill-table app* (list "house" 
	                       (obj budget*  (table)
                                forecast* (table))))

    (fill-table ((app* "house") 'budget*) (list "roof" 1996.0))
    (fill-table ((app* "house") 'forecast*) (list "roof" 1996.0))
    (fill-table ((app* "house") 'budget*) (list "windows" 1000.00))
    (fill-table ((app* "house") 'forecast*) (list "windows" 1800.0))
so instead of doing this:

    (def area-situation (area sub-area)
         (let area-budget (((app* area) 'budget*) sub-area)
         (let area-forecast (((app* area) 'forecast*) sub-area)
         (let delta (- area-forecast area-budget)
         (if (is delta 0.0) 
               (let newval (list sub-area 200) 
                   (fill-table ((app* area) 'budget*) newval)))
         (prn (list "forecast " area-forecast " budget " (((app* area) 'budget*) sub-area))))))
    )

    arc> (area-situation "house" "roof")
    (forecast  1996.0  budget  1996.0)
I was thinking it would be nice to set up all my pointers at the beginning, then the last few lines of code ,where the meat is, become less cluttered with syntax and more about what, from a conceptual perspective, I am doing:

note: p = (point this (at that))

    (def area-situation (area sub-area)
         (p budget ((app* area) 'budget*)) 
         (p forecast ((app* area) 'forecast*))
         (p area-budget (budget sub-area))
         (p area-forecast (forecast sub-area))
         (= delta (- area-forecast area-budget))
         (if (is delta 0.0) 
              (let newval (list sub-area 200)
               (fill-table area-budget newval)))
         (prn (list "forecast " area-forecast " budget " area-budget))
    )

    arc> (area-situation "house" "roof")
    (forecast  1996.0  budget  200)
So you'll notice a few things; in function 1 - the last line requires having the full syntax for getting the roof budget; otherwise even though it's been re-set to 200; the let statement prior had already been set to 1996.0; so it forces me to re-use the syntax again; where ares the pointer notion in function 2 would not.....

Anyways - just the way my mind thinks (like a big spreadsheet haha). :)

T.

-----

2 points by CatDancer 5958 days ago | link

When you have two expressions that are similar,

  (((app* area) 'budget*) sub-area)

  (((app* area) 'forecast*) sub-area)
write a function consisting of the parts that are the same, and make the parts that are different into variables:

  (def (price area type subarea)
    (((app* area) type) subarea))

  (def area-situation (area sub-area)
    (let area-budget (price area 'budget* sub-area)
      (let area-forecast (price area 'forecast* sub-area)
         (let delta (- area-forecast area-budget)
I would continue iteratively with this process of turning similar expressions into functions, but it looks like you may have a bug in your code? You store a new budget but print out the old one. Unless that's what you wanted?

There are a couple of advantages to this process of noticing expressions in your code that are similar and turning them into functions. First, you don't have to figure everything out in advance. You write some code and get it to work right. Then you look for similar expressions and turn them into functions. In practice this works a lot better than trying to figure out what functions you're going to need ahead of time.

The second advantage is that it makes your code easier to change. For example, suppose you wanted to change your representation of your prices from tables inside of tables into lists, or perhaps one table with a compound key. If you have lots of places where you say (((app* area) type) subarea)) then you'd need to change all of those, but if you have a few functions like price then you only need to change those.

-----

1 point by thaddeus 5957 days ago | link

ugh, sorry.

The code didn't have the bug the results I gave did (too much copying and pasting) :)

the first function actually returns 200. (forecast 1996.0 budget 200)

what I had intended to convey was that I had believed I was required to use the full syntax (((app* area) 'budget*) sub-area) in order to get the 200, which I did, but I wanted to just use 'area-budget' to make it more readable.

But as I learned there were so many things I was doing wrong it wasn't funny ... even though I am laughing now. bewahahahah ! :)

Thanks for the reply. T.

-----

1 point by CatDancer 5958 days ago | link

I'll take a look at this, but it may be a couple days before I have a chance to get to it.

-----

1 point by thaddeus 5958 days ago | link

no worries, it's not a real problem I have to solve. I'm just trying to figure out what options/techniques are available.

Thanks. T.

-----

3 points by conanite 5958 days ago | link

app* is a nested structure something like this:

  app*
    yardwork
      budget
      forecast
    house
      budget
        roof = 1996.0
        windows = 1000.0
      forecast
        roof = 1996.0
        windows = 1800.0
And you want a clean way to access, for example, (((app* 'house) 'budget) 'roof), given 'house and 'roof as parameters.

Am I right so far?

An alternative definition of area-situation might look like this:

  (def area-situation (area sub-area)
    (with (budget   ((app* area) 'budget)
           forecast ((app* area) 'forecast))
      (if (is (- (budget sub-area) (forecast sub-area)) 0)
        (= (budget sub-area) 200))
      (prn "forecast " (forecast sub-area) " budget " (budget sub-area))))
You can use 'with to create variables pointing just to the two tables you need and then there's less digging to do when you need to look up or alter values.

You might get better mileage by changing the data structure though if that's possible:

  app*
    yardwork ...
    house
      roof
        budget = 1996.0
        forecast = 1996.0
      windows
        budget = 1000.0
        forecast = 1800.0
Then, area-situation becomes even simpler:

  (def area-situation (area sub-area)
    (let situation ((app* area) sub-area)
      (if (is (- (situation 'budget) (situation 'forecast)) 0)
        (= (situation 'budget) 200))
      (prn "forecast " (situation 'forecast) " budget " (situation 'budget))))
Arc doesn't really have "pointers" (at least not in the c/c++ sense) - you either have global variables, or local (lexically-scoped) variables. So you can create a local variable pointing to the innermost table using 'let or 'with. Oh, I said "pointing" - well, they're kinda pointers.

Does that point you in the right direction, or did I miss the point entirely?

btw with the hot new special-syntax you can write app.area.sub-area instead of ((app area) sub-area) - see http://arclanguage.org/item?id=9220

-----

1 point by thaddeus 5958 days ago | link

wow!

i didn't have an appreciation for the 'hot new special-syntax' until I compared my original hack against your last function with the infixing....

    (def area-situation (area sub-area)
        (let situation app*.area.sub-area
          (if (is (- situation.budget situation.forecast) 0.0)
            (= situation.budget 200)
          (prn "forecast " situation.forecast " budget " situation.budget))))
This is awesome!

T.

-----

1 point by thaddeus 5958 days ago | link

    *Am I right so far?*
yep.

I have to spend more time using 'with'; it's not a well well used tool in my tool shed as it should be.

and your last solution looks great to me.

thanks. T.

-----

2 points by fallintothis 5958 days ago | link

Accepting the hypothetical that there's not a clear-cut way to simplify the data structures (hey, it happens), I can't think of much to do. I know what it is you want to do, as the problem does crop up from time to time -- trying to make use of the expression instead of the value of an expression. An obvious way to solve this would be to introduce a macro, e.g.

  (= app* (table))
  
  (deftem cost-sheet  ;or whatever.  probably a bad name.
    budget   (table)
    forecast (table))
  
  (= (app* 'house) (inst 'cost-sheet 'budget   (obj roof 1996.0 windows 1000.0)
                                     'forecast (obj roof 1996.0 windows 1800.0)))
  
  (mac budget (area sub-area)
    `(((app* ,area) 'budget) ,sub-area))
  
  (def area-situation (area sub-area)
    (withs (area-budget   (((app* area) 'budget)   sub-area)
            area-forecast (((app* area) 'forecast) sub-area)
            delta         (- area-forecast area-budget))
      (when (is delta 0.0)
        (= (budget area sub-area) 200))
      (prn "forecast " area-forecast "budget " area-budget)))
But this isn't a very palatable solution -- you'd need to define macros for each field, and even then they're only shortcuts, really. It'd be easier if there were a shorter way to do nested indexing (which there will be, come arc3: http://arclanguage.org/item?id=9163).

Upon writing this and finding someone else replying, I notice that conanite's post http://arclanguage.org/item?id=9326 contains probably the best solutions, though.

-----

1 point by thaddeus 5958 days ago | link

I like the mac idea too. if the concepts like "budget" and "forecast" are the main data concepts of the program; then I can see being able to re-use the macro a lot. Also I have to read up on 'deftem' and 'inst'.

thanks, T.

-----


you're my new hero. :)

-----


LOL. hmmmm...

    arc> (toerr ((or (no t) toerr)))
    nilnil
Guess that means I should not error!

T

-----

3 points by thaddeus 5960 days ago | link | parent | on: Last call for Arc bugs

Initially I tried to make operator/variable names descriptive, but as time went on I became tired of typing every descriptive name again and again so, obviously, I tried to establish a balance between readability and convenience... However, the more I code the more I notice the names become shorter and find it takes effort to achieve meaningful names. That balance is going to be different person to person, but I will hazard a guess that the more you code the shorter the names become.

as an example (not that the function works):

    (def fill (table-name with)
         (filltable table-name with))

    (def fillcup (with size)
        (let cup size
            (fill cup with)))

    (fillcup "coffee" 8oz*)
The above is ideally how I would name names, but then find myself trying to incorporate the data type into the name...

    (def fillcup (with-string size-table)
        (let cup size-table
            (fill cup with-string)))
which I think is equally as bad as:

    (def fillcup (s tb)
        (let cup tb
            (fill cup s)))
This last one is bad as 'tb' may tell it's a table, but what is it conceptually? A size table...

So here are my options:

    * the idealized version isn't descriptive enough
    * if all my code were fully descriptive I would be
      worse off reading and typing everything.
    * the short form is just as bad as both the idealized
      version and the descriptive version.
So it doesn't surprise me that people go with the short form, the lesser of evils - perhaps ?

The worst part is that because all the options suck I end up doing things like:

    (def fillcup (with-str size-tb)
        (let cup size-tb
            (fill cup with-str)))
Which by then I hate my code and should have just stuck with the idealized or the short.

I personally wish there were a means to quickly identify the data-type without having to incorporate it into the name, something like a hover tag - this would, more often, allow myself to afford the meaningful without being overly descriptive.

(I currently use textmate to write code and the terminal for the repl).

Just and opinion from a hobby programmer with only a few hundred hours programming experience.

T.

-----

2 points by conanite 5960 days ago | link

Have a look at http://steve-yegge.blogspot.com/2008/02/portrait-of-n00b.htm... ... you might find it reeks of arrogance, or you might enjoy it:

"The sticking point is compression-tolerance. As you write code through your career, especially if it's code spanning very different languages and problem domains, your tolerance for code compression increases. It's no different from the progression from reading children's books with giant text to increasingly complex novels with smaller text and bigger words."

If my understanding is vaguely correct, Yegge argues for compact code for the same reasons pg does.

I personally wish there were a means to quickly identify the data-type

Something that an editor for a dynamic language can give you is run-time analysis of your code - so, indeed, a mouse-over could in fact give you a list of the types assigned to any given symbol. This is something I'd love to get welder to do ... it's entirely possible, in theory :)

Alternatively, you could write your own function definition macro that lets you specify param types and checks them for you at runtime:

  (typed-fn fillcup ((string with) (table size)) 
    (let ...
But my tendons recoil in horror at the implications of this. Remember: strong typing hurts your keyboard!

-----

2 points by thaddeus 5960 days ago | link

I enjoyed the first half - then he went on and on and on....

My goal is to try making code readable enough that documentation or 'metadata' is barely needed. I'm going to rework my code and start keeping my code idealized - not descriptive - not short.

I'm going see how it works when I drop the data type tagging all together and hope one day when I am a little more knowledgeable I will be able to craft a solution.

Maybe in a few years I'll let you know how it went :) T

-----

More