Arc Forumnew | comments | leaders | submit | rocketnia's commentslogin
4 points by rocketnia 5553 days ago | link | parent | on: Share your useful functions/macros

Macro: (thunk body). It's simple enough. Just like the square bracket syntax covers one-argument functions, this can cover zero-argument functions.

  (fn () (err "Ack! You called me!"))
  (thunk:err "Ack! You called me!")
When the function body is long, this helps reduce indentation and parentheses. (That's sort of a hobby of mine, I guess. :-p )

-----

3 points by evanrmurphy 5538 days ago | link

> Macro: (thunk body). It's simple enough. Just like the square bracket syntax covers one-argument functions, this can cover zero-argument functions.

A side effect of making all function arguments optional [1] is that the square bracket syntax can then cover zero-argument functions too, so we get this additional (shorter) way to express your thunk example:

  [err "Ack! You called me!"]
---

[1] http://arclanguage.org/item?id=13030

-----

1 point by akkartik 5538 days ago | link

Nice. So you can use [] if it saves you a set of parens, and thunk to sidestep the implicit function call:

  (thunk 34)

-----

1 point by rocketnia 5538 days ago | link

Actually, I don't use 'thunk when it doesn't save me parens. Both "thunk" and "fn ()" take up the same number of characters (albeit not the same number of tokens), and I figure Arc programmers will have to look up what 'thunk means more often than they look up 'fn. :-p

Incidentally, it actually does save parens in that case:

  thunk.34

-----

1 point by akkartik 5552 days ago | link

Like do but without a set of parens. Nice. Wish I could define do in terms of thunk, but it's too early in arc.arc.

-----

1 point by rocketnia 5553 days ago | link | parent | on: Share your useful functions/macros

If I may:

  (string:big long
    (hairy gigantic)
    (immense and complicated (function)))
No macro is needed, and there's less indentation and fewer parentheses. You can also improve on the 'as macro by allowing for (as (type expr)) in addition to (as type expr). That lets you cut down on indentation and parentheses just as much:

  (as:string:big long
    (hairy gigantic)
    (immense and complicated (function)))

-----

2 points by akkartik 5553 days ago | link

as is still useful for coercing to other types.

-----

1 point by rocketnia 5552 days ago | link

Sure is, but I'm just a bit of an un-fan of 'coerce. I've already mentioned unary functions being more convenient with a:b ssyntax. On top of that, there's oftentimes more than one obvious way to get one type of value from another, and while you could use custom types to represent more coercion targets, like (rep:coerce x 'assoc-list), I think that's a step in the wrong direction, just 'cause I don't know where the benefit is.

-----

1 point by akkartik 5552 days ago | link

Ah I see. But I don't follow what you mean by unary a:b.

-----

1 point by rocketnia 5551 days ago | link

The ssyntax expressions (a:b ...), a.b, and a!b all pass only one argument to a, so ssyntax (currently) makes one-argument functions and macros more convenient than other kinds.

-----

1 point by akkartik 5551 days ago | link

Ah, that makes sense. And why is it bad to have more than one way to convert one type into another?

-----

1 point by rocketnia 5551 days ago | link

Eh? XD There's nothing wrong with that. My point was that it doesn't make a whole lot of sense to designate just one conversion for each target type when there are lots of options.

(Note from the future: What follows doesn't really continue that response. I just started randomly considering a few more angles. ^_^ )

Most of the time, [coerce _ 'string], [coerce _ 'sym], and so forth just end up being more verbose ways of saying things like [string _] and [sym _]. Almost all the uses of 'coerce in Arc 3.1 and Anarki are like that, where they hard code the target type, so that it's just like the name is coerce-cons or coerce-string but without any synergy with ssyntax. There are two exceptions:

  (def sort (test seq)
    (if (alist seq)
        (mergesort test (copy seq))
        (coerce (mergesort test (coerce seq 'cons)) (type seq))))

  (def inc (x (o n 1))
    (coerce (+ (coerce x 'int) n) (type x)))
These functions have the special property that they can be used with all sorts of types as long as 'coerce is capable of translating back and forth. If you want to make a custom type that's compatible with them, you only need to replace or extend 'coerce to do it, rather than, well, replacing 'sort or 'inc. :-p This technique was sort of rediscovered here recently: http://arclanguage.org/item?id=12340

Now that I think about this, my position has softened even more, but I'm still a bit stubborn. Even if 'coerce is only used as a way to convert something back from the type a calculation needs to manipulate it in, there's still an arbitrary choice being made between multiple behaviors. If some generic string utility wants to convert '(#\[ #\1 #\]) to "[1]" and back, but some JSON utility wants to convert '(1) to "[1]" and back, then (coerce "[1]" 'cons) needs to have two meanings at once.

Of course, if it comes to that, it's easy to just make the JSON utility convert from '(1) to (annotate 'json-encoded "[1]") and back instead. I think I have no escape from that. XD Any corner case I come up with is going to be at least as you're-not-gonna-need-it as 'coerce is. ^_-

Nevertheless, while I was arguing with myself, I came up with an experimental type-independent (and therefore 'coerce free) way to model back-and-forth transformations. It's a pretty obvious design, but I somehow managed to make it complicated and arbitrary in certain ways. :-p Here it is in case anyone's interested:

  (def encode-int (unencoded)
    (list `(type ,type.unencoded) int.unencoded))
  
  (def decode-int (recovery-notes encoded)
    (let fail (fn () (err "Unexpected 'decode-int case!"))
      (case do.recovery-notes.0 type
        (case do.recovery-notes.1
          string  string.encoded
          int     encoded
                  (do.fail))
        (do.fail))))
  
  (= encoding-int (annotate 'encoding
                    ; This is more hackable than
                    ; (list encode-int decode-int).
                    (list (fn args (apply encode-int args))
                          (fn args (apply decode-int args))))
  
  (def fn-through (encoding unencoded body)
    (withs ((encode decode) rep.encoding
            (recovery-notes encoded) do.encode.unencoded)
      (do.decode recovery-notes do.body.encoded)))
  
  (mac through (encoding var . body)
    `(fn-through ,encoding ,var (fn (,var) ,body)))
  
  (def inc (x (o n 1))
    (through encoding-int x
      (+ x n)))
(Hmm, is this related to http://en.wikibooks.org/wiki/Haskell/Monad_transformers#lift? >.> )

-----

2 points by akkartik 5551 days ago | link

"it doesn't make a whole lot of sense to designate just one conversion for each target type when there are lots of options."

Ah, now I follow. But often there's one kind that applies far more often than alternatives. And it's good for coerce to give it. For other type combinations it's good to know that coerce is complete, and that it'll give some sort of conversion. But you're right, I don't know if this ever makes code shorter. Perhaps this is yet another example of programmer's OCD, that insidious need to have things be aesthetic even when they don't matter.

I just started randomly considering a few more angles. ^_^

I'm starting to realize that's the reason I have a hard time following what you write :) If I may make a suggestion, make a list. I find your long comments are often too terse. Often they contain enough stuff for three or four distinct postings or comments. But the transitions are abrupt, perhaps because you're trying not to be even more long-winded. If you gave each idea its own post or comment it would have more room to breathe, and I'd be able to return to each one at my leisure. Feel free to post new submissions with substantial ideas. We hardly have enough submissions here.

Like your code idea at the end of the comment, and the suggestion that it's like monad transformers. I'd love to see a post elaborating on it. I'd love even more to see a yegge-sized elaboration of all your thoughts on coerce and what 'synergy with ssyntax' means. Perhaps they haven't settled down yet, but keep it in mind when they do :)

Sometimes I feel I would spend an hour with any one of your ideas if you'd spent just a few extra minutes with it.

Hopefully this is constructive feedback. Perhaps it's just me having poor comprehension; you should ask for others' opinions.

-----

2 points by rocketnia 5550 days ago | link

I have a hard time following what you write :)

Thanks for telling me that. ^^;

My usual process is that I'll take a few hours to write a comment, then I'll run out of time and decide to come back later to finish it up, and then I'll never go back to that draft (but I might start from scratch on the same topic). Occasionally I'll finish something in time to post it.

Recently, I have less time than I'm used to, so I've been posting things even if they're rough, in case someone gets value out of it anyway. I guess this makes my posts into scatterings of half-ideas, based on things I've been thinking to myself but only now had a reasonable excuse to mention. (Usually I shoot for a few organized, mostly full ideas, which also have very good excuses to be mentioned. :-p )

Thanks to your suggestion, I'll try harder to talk about things even when there isn't an excuse. ^_^

-----

1 point by rocketnia 5553 days ago | link | parent | on: Defcall for numbers: Multiplication?

It's very reminiscent ... also of using little dots, as in "4·x·y".

Wow, I missed that. XD I was mainly thinking of juxtaposition.

The only possible problem I can think of is difficulty of (efficient) implementation.

Yeah, certainly an issue. Optimized code can use (* 4 a c) like usual though.

Other thing

Custom types should already use 'annotate when they need custom 'defcall behavior, right? For instance, if ax^2+bx+c is built using (annotate 'poly (list a b c)), you can index it using rep._.i and call it using _.i. If you're talking about having polynomial calls do polynomial multiplication instead when they're called, then you may have a design conflict (although I think the cases are mostly distinguishable here).

Anyway, as you sorta suggest, the multiplication of diverse things is still a bit weird in general. The concern I have in mind is that multiple dispatch rears its head. I think I'd end up doing something like this (untested!):

  ; Extend numbers so that they use '* as their call behavior.
  (mac defmulttype type
    `(defcall ,type form (apply * form)))
  defmulttype.int
  defmulttype.num
  
  ; Define another variable bound to '* so we won't lose track of it
  ; when we redefine it.
  (= *-base *)
  
  
  ; Define an extensible binary version of '*. This part's rudimentary
  ; for laziness's sake.
  
  (def *-binary (a b)
    (err:+ "Can't multiply " a " by " b "."))
  
  (def fn-defmult (test-a test-b body)
    (zap testify test-a)
    (zap testify test-b)
    (let old-*-binary *-binary
      (= *-binary (fn (a b)
                    (if (and do.test-a.a do.test-b.b)
                      (do.body a b)
                      (do.old-*-binary a b))))))
  
  (mac defmult (test-a test-b . body)
    `(fn-defmult ,test-a ,test-b (fn (a b) ,@body)))
  
  
  ; Define '* in terms of '*-binary. It's left-associative.
  (def * args
    (case args nil 1
      (reduce *-binary args)))
  
  ; Make multiplication with a nonnegative integer on the left use '+.
  (defmult [and (isa _ 'int) (<= 0 _)] [do t]
    (apply + (n-of a b)))
  
  ; Provide the multiplication cases that used to be built in,
  ; overriding the integer rule in the process.
  (defmult number number
    (*-base a b))
This gives just enough multiple dispatch for people to put (defmult [isa _ 'poly] [isa _ 'int] ...) in one library and (defmult [isa _ 'poly] [isa _ 'snargle] ...) in another one, and they can use (defmult 'poly [do t] ...) if they only need single dispatch.

I'd also give an actual example of using polynomials, but I'm out of time. :-p It would have just been an exploration of having (defmult [isa _ 'poly] isa-poly-arg ...) and (defmult [isa _ 'poly] [isa _ 'poly] ...) be separate cases.

-----


If [] wasn't already used for lambdas, I could've suggested using it as a raw-list literal. [1 2 3] wouldn't be that bad.

I don't think odd parentheses like [...] are substantially more convenient than operator applications like (list ...). In fact, when editing in a bare-bones text editor, it's a slight pain to have to figure out whether )))]))]))) is the right combination of brackets. :-p

That doesn't mean it's a bad idea altogether. I think Clojure probably has the best practical use of brackets. It uses [] for literal lists just like what you're talking about, but it also generally uses [] brackets wherever there's no operator-and-body format that needs highlighting and indenting. They're used for argument lists, for instance. I haven't heard of someone setting up an editor to take advantage of that consistency, but I'd be surprised if that wasn't the reason for it. ^_^

-----

2 points by hasenj 5553 days ago | link

> ))]))])))

One of the ideas lurking in my head was a symbol to close all open parenthesis

For example, assuming [] isn't used for anything:

  (def fun (args)
    (a (b (c (d)))))
would be written as:

  (def fun (args)
    (a (b (c (d))]  
where ] would tell the interpreter to close everything. Or maybe just close the nearest open parenthesis that's at the beginning of a line.

Granted, something like (a (b (c (d] looks a bit odd, but this looks less odd:

  (a (b (c (d (e (f (g (h)))]
And you'll be able to insert stuff in the middle without having to remember to balance parenthesis at the end:

  (a (b (c (d (x y) (z (e (f (g (h)))]

-----

1 point by rocketnia 5553 days ago | link

Didn't pg talk about this use of ] in one of the early posts on Arc?

I shy away from it only 'cause it reduces the number of editors which can make sense of the brackets.

-----

1 point by akkartik 5553 days ago | link

(Which is reason against PLT's use of [], but doesn't affect arc's chosen use.)

Incidentally [] has one major advantage over (): it doesn't require pressing the shift key every single time. In my vim and emacs I've swapped the two sets of keys in lisp mode.

-----

2 points by rocketnia 5553 days ago | link

Which is reason against PLT's use of [], but doesn't affect arc's chosen use.

Hmm? I don't provide any reasons against Racket's claim that "Using square brackets in a few key places makes Racket code even more readable." In fact, I think it does aid a bit in readability, but it doesn't help when my goal is to correct sloppy brackets. XD

What I am saying is that Arc's [+ 1 _] syntax is about as convenient as (f- + 1 _) or (f-:+ 1 _). Arc also shares the ))]))) issue, a little. It would be more noticeable if more operators accepted functions as their last argument rather than their first argument.

Incidentally [] has one major advantage over (): it doesn't require pressing the shift key every single time. In my vim and emacs I've swapped the two sets of keys in lisp mode.

You mentioned this a while ago, so I've been using only [] in my languages-in-progress. ^_^ It also helps that I begrudge () and {} for looking too similar to each other. :-p The one thing I'm worried about is that ] and [ might be less distinguishable from each other than ) and ( are.

-----

1 point by akkartik 5553 days ago | link

It would be more noticeable if more operators accepted functions as their last argument rather than their first argument.

Yeah, but they don't. Lisp idiom tends to be to put the values being operated upon last, and with good reason: you want to put last the arg most likely to be a temporary. Otherwise you risk separating function calls from their args. Compare:

  (some-function
     (some-verbose-computation
       ...
       ...)
     arg2 arg3)
with:

  (some-function arg2 arg3
    (some-verbose-computation
      ...))
Since there's this major structural constraint I think any dispatch in lisp should be on the type of the last arg. (http://arclanguage.org/item?id=12646)

-----

1 point by rocketnia 5554 days ago | link | parent | on: Defcall for numbers: Multiplication?

This is kind of a reply to http://arclanguage.org/item?id=12841

Just quoting that for linkification. ^^;

-----


I was going to say something almost just like this, so kudos. ^_^ However, I cut myself off 'cause I realized that in someone's mind, 6 could primarily be a function that constructs lists that begin with 6, and only incidentally has useful behavior with '+, '-, etc. :-p To be fair, that's pretty silly, and you have other points that are good regardless.

-----


In Anarki, you can try out something similar really quickly.

  (defcall int self-and-args
    copy.self-and-args)       ; The 'copy may be unnecessary....
This should cause (1 2 3) to evaluate to a list. You can do this for types other than 'int as desired.

I actually think your idea conflicts at a design level with 'defcall. With 'defcall, there's no real guarantee that custom types will use any given default behavior, so you can only rely on the default for built-in types, and at that point you might as well just 'defcall them all one by one rather than having a default.

-----

1 point by akkartik 5555 days ago | link

; the 'copy may be unnecessary....

Just use idfn.

-----

1 point by rocketnia 5554 days ago | link

How do you mean? Under certain implementations of defcall, you might be able to get away with (= call*!int idfn), but Anarki's current implementation is a shortcut for this kind of code instead:

  (defcoerce fn int (self)
    (fn args
      (apply list self args)))  ; might be able to use 'cons here...
My confusion about 'copy and 'cons is founded on this part of arc.arc:

  ; Can return to this def once Rtm gets ac to make all rest args
  ; nil-terminated lists.
  
  ; (def list args args)
  
  (def copylist (xs)
    (if (no xs) 
        nil 
        (cons (car xs) (copylist (cdr xs)))))
  
  (def list args (copylist args))
I don't hold onto argument lists very often, but when I do, I occasionally wonder whether I should be copying them first. I think this is the first time I've actually let that concern change my code, though. What do you think?

-----

2 points by aw 5554 days ago | link

In (fn args ...), args will be a MzScheme list terminated by Mzscheme's '() instead of Arc's nil. It's usually hard to tell the difference, since the Arc runtime treats '() like nil when it can. There are a few odd corner cases where you'll notice it, for example if you use args as a key in a table, it will be a different key value than if you construct the same list using list.

-----

1 point by rocketnia 5554 days ago | link

Ah, right. Part of me's trying to think of a way to use an extensible 'iso (like akkartik's or mine) so it could be used as a table key comparator, but without the burden of maintaining a corresponding extensible hash function. (That is, the hash function would be automatic somehow.) How feasible do you think that would be? Maybe we should have the extensible hash function, but have convenience macros that extend both functions at once?

My main motivation is to remove all traces of the non-extensible Racket 'equal?.

-----

2 points by elibarzilay 5553 days ago | link

Not that it matters much in this context, but racket's equality is extensible: http://docs.racket-lang.org/reference/booleans.html#(def._((...)

-----

2 points by akkartik 5553 days ago | link

That is awesome, thanks for the tip.

Now I want to rant about Racket documentation.

You tell me equality is extensible, and now I know that, and I go look at that page and scan it from top to bottom. I do the usual things I do to read stuff online, and I've been pretty successful with my reading, my reading comprehension scores were excellent in standardized tests, I have a phd that was about nothing if not reading opaque publications, and now I'm faced with this page and I still have no idea how to tell that equality is extensible, or how to go about extending it. If you hadn't told me I'd look at that page about booleans and have no reason to expect it to bear the slightest relationship to equality for complex user-defined data structures[1]. Search for 'extensible'. Nope. Oh, 'inspectable structures.' What the sam hill are those? It has to do with prop:equal+hash, which doesn't even look like a single token to my eyes. Is it a function? How do I use it? All this goes through my mind in a flash, and all I feel is stupid.

I keep waiting for the racket reference to gradually become clear, but it's been a year now of poring over it and I don't think it'll ever happen. It's a blind spot, platform nine and three quarters, just around the corner but at ninety degrees from all three dimensions that I can see. I would never ever have noticed that equality is extensible until you told me that was so.

[1] I scan back up and it's right there in the title: "Booleans and equality." See what I mean about feeling stupid? Why should booleans and equality be grouped together? Why should equality be in the section on datatypes and not say structures?

-----

2 points by elibarzilay 5553 days ago | link

0. Note that the actual link is broken -- it's missing a ")" in the end (it's there, but it wasn't included in the url for some reason (I don't know about the local markdown language...))

1. Yes, some of these issues are known, and we're in a constant race with improving the documentation in various ways. As always, emails to the mailing list or bug reports -- or better: suggestions and possibly patches -- all of these are always welcome.

2. In this particular case, I didn't need to guess -- I knew that it was added, so I just needed to find that reference.

3. But if I were trying to find it, the first place I'd look would be the documentation for `equal?' -- and it is indeed there, at the end of the second paragraph.

4. As for how you use this property, the text that I referred to has a link to "Structure Type Properties", which describes all of that.

5. Re the organization -- booleans and equality are grouped because they're related... It also appears as the first subsection in the datatypes chapter, which makes sense there. If you have an idea how to organize it better, then see #1.

6. Yes, it would be nice to have some section that lists all of the properties that could be used for structs. The main problem with doing this is that it's an open system, so anyone can add more properties, but it won't make sense for the core to list properties from modules outside of it. This was discussed recently, and I don't think that anyone had an idea what to do about it.

-----

1 point by akkartik 5553 days ago | link

"if I were trying to find it, the first place I'd look would be the documentation for `equal?' -- and it is indeed there, at the end of the second paragraph."

Part of the problem is that I never tried finding it, because it didn't occur to me that racket would have extensible equal?

A few months ago I was flattened - absolutely flattened - to find out that PLT has optional args and keyword args. (http://arclanguage.org/item?id=12591)

I have no idea why this is. Perhaps the problem is that people expect scheme to be a small language.

-----

3 points by elibarzilay 5553 days ago | link

Well, the optionals and keyword arguments have been in for a long time now... In fact, the current thing is a second iteration after a first facility that was more CL-like...

In any case, Racket is certainly not a small language...

-----

1 point by akkartik 5553 days ago | link

Yes, as I was ranting I was feeling bad for not having contributed to improve things. I wasn't being rhetorical about feeling stupid and guilty. Lack of understanding is a barrier but no excuse. For me to say "I have a phd, but this I can't read" is akin to saying "I've learned spanish, but chinese is hard." Well, d'uh. Deal.

Perhaps PLT needs a user guide in addition to a reference, a level of redundancy with a kinda orthogonal organization (focusing on complex tasks involving multiple advanced concepts) that'll help people triangulate on understanding, or just use what works for them.

-----

3 points by elibarzilay 5553 days ago | link

Heh, excellent idea: http://docs.racket-lang.org/guide/

(See also other such documents at http://docs.racket-lang.org/getting-started/)

-----

1 point by akkartik 5553 days ago | link

I've seen that before. Why have I not paid more attention?

Here's the extremely clear guide on extensible equality: http://docs.racket-lang.org/guide/define-struct.html#%28part...

I'm going to withdraw my rant. It's something specific about my stupidity that's causing me these problems. Still investigating.

Ah, I think I see what's been happening. Since I started out with arc I've restricted myself to the mzscheme 'ghetto' and not paid as much attention to the racket language itself. My attitude was "who knows what works in mzscheme and what doesn't." This has been the root cause of my troubles, I think.

I'm going to focus on core racket now.

-----

2 points by evanrmurphy 5553 days ago | link

Thanks for the link to Guide: Racket. I've also had trouble getting into Racket's documentation, but this looks like a much more accessible starting point than Reference: Racket.

-----

1 point by rocketnia 5552 days ago | link

(Fixed link: (http://docs.racket-lang.org/reference/booleans.html#(def._((...). I fixed it by putting another pair of parentheses around it to fool the regex. :-p )

Oh, awesome. At one point I think I knew that, too, but at some point I saw 'make-custom-hash (http://docs.racket-lang.org/reference/dicts.html#(def._((lib...) and forgot about it.

Given that prop:equal+hash exists, are there any commonly used convenience macros for implementing it for a structure? It's niftiest if they support cyclic structures too, since Racket's equality API makes that possible, but I'm not picky. ^_^ I'll probably just write something myself either way, but I'm on the lookout for inspiration.

-----

1 point by akkartik 5554 days ago | link

Oh, I didn't think that much about it. I just tried this in anarki:

  (defcall int self-and-args
    idfn.self-and-args)
and it seems to work ^_^. I can't come up with a counterexample that requires copying. Can you? Otherwise let's just not copy until something breaks. Then we'll learn something.

-----

1 point by akkartik 5554 days ago | link

You know I think I totally misunderstood your original code comment. When I read it now my response to use idfn seems kinda facetious (I was seriously suggesting it, don't know what I was thinking.)

-----

1 point by rocketnia 5554 days ago | link

Well, I don't hold it against you. :-p It gave me an excuse to elaborate about my confusion too. >.>

I think I agree with you that we shouldn't worry about holding onto the argument list as long as it isn't a tangible problem. I'm interested to hear if someone knows of a problem though. ^_^ (Edit: Oh, aw posted an example.)

-----


Erm... he recommends using intended types as explicit arguments? Like, (coerce my-list 'list 'string) and (equivalent list1 list2 'list)? Sounds a lot like the kind of "Time time = new Time();" redundancy you get in Java-like blubs. ^_^

I do think it's a more consistent approach, and I usually side with what's consistent, but here I think we can do way better.

How about another technique Java uses: There's a single standard equals() method for non-reference comparison, and it has a custom specification for each type. There's no need to disagree with it, 'cause you can create a wrapper object with custom implementations of equals() and hashCode() and use that to wrap all your Map keys, etc.

In a language like Arc, this would create code of the form (coerce (annotate 'list my-list) 'string) instead. However, 'my-list can be wrapped up as a 'list once in order to keep the rest of its uses brief.

Another lesson to take from that article besides the one it promotes is to refrain from having values like nil which can be seen as being multiple types. If lists were all tagged 'list in the first place, it would be obvious which code was responsible for tagging them. The biggest drawback, I think, would be that each procedure which returned a new list would have to allocate a wrapper for that list. (But then that's only a performance issue.)

The other obvious objection is that (if my-list ...) wouldn't check the list for emptiness. Well... I like that idea, myself. People can always say (if empty.my-list ...) to test collections, and Arc programmers already have to do that now for strings and tables.

-----

1 point by akkartik 5556 days ago | link

"you can create a wrapper object with custom implementations of equals() and hashCode()"

Yep, it was interesting to me because you can simply avoid all his issues with extensible abstractions like anarki's coerce or defgeneric.

-----

1 point by rocketnia 5556 days ago | link | parent | on: Question: How do I use Arc?

I've run Arc on Windows for a long time, but having just started into Ubuntu a week or so ago (now settled into Linux Mint), I have to agree with you that it's a pretty good option. ^_^ Most of the trouble I've had has been with getting the network connection to work, and unless I'm mistaken, VirtualBox makes that much less of an issue.

Once Linux is working, getting Arc to work is easy. :-p

-----

1 point by aw 5556 days ago | link

Tell me what you like about Linux Mint? I'd like to recommend a Linux distribution, instead of just saying Ubuntu by default.

Yes, an advantage of the virtual environment is that the work of "drivers" in the virtual environment are actually performed by drivers in the host operating system. So if you have for example networking working in the host environment, then it will also work in the virtual environment... without fiddling around with Linux network drivers for your hardware.

-----

1 point by rocketnia 5555 days ago | link

I want a personalizable interface, I'm very new to Linux, and I don't mind using unfree software like media codecs (something Ubuntu had kept bothering me about ^_^ ), so when I encountered the Linux Mint description at http://distrowatch.com/dwres.php?resource=major, it seemed like a good fit.

Also, I vaguely had in mind that I wanted a theme with hints of green in places (probably because I had seen Linux Mint somewhere before), and the release of Linux Mint 10 happened the day before my search, so it was sorta meant to be. :-p

I had some trouble with both, which Internet searching was mostly able to resolve. But I never figured out the whole too-much-KDE-on-GNOME thing, for instance. @_@

Right now my network connection is really the most annoying thing, but it's passable as long as I'm patient enough to unplug my USB dongle, plug it back in, and reboot until the magic happens. (One reboot's almost always enough.) Usually I'm not that patient 'cause I'm still trying to figure this out, so I fumble with commands like "service network-manager restart" trying to find some combination of them that will actually work this time around. XD It'd be awesome if someone could help me out with this. ^_^;

-----

1 point by shader 5556 days ago | link

I prefer Mint mainly because of the decent looking initial theme, and the superior driver support. I've almost never had any issues getting Mint to install properly with everything working on the first try. Also, the install and configuration process is extremely streamlined and easy to follow. Not that Ubuntu is bad, per se, but Mint seems marginally better.

I'd definitely recommend Mint first for someone not yet well acquainted with linux. The ease of install, simple menu, and software installation tool make it a lot nicer on new users.

I run a virtual boxed Mint in seamless mode on Windows 7 continuously, to use as a shell for ssh and programming in certain languages (like arc or c), and I use a heavily modified Mint on my netbook as well.

-----

1 point by rocketnia 5561 days ago | link | parent | on: Rock climbing -- and How to Help

I've posted a pretty big response in your comments. I'm plugging it here just to make sure people don't miss it when they look for new Arc Forum comments. ^_^

-----

More