Programming

on fundamental matters such as existence, knowledge, values, reason, mind and ethics.

Moderators: Calilasseia, ADParker

Re: Programming

#61  Postby jamest » Mar 12, 2012 1:23 pm

advaitya wrote:
stalidon wrote:
advaitya wrote:I fail to see the philosophy in this thread? Ought to be shoved in some other appropriate forum.


Just wait, the philosophy is coming. From Wiki: "Lambda calculus has applications in many different areas in mathematics, philosophy, and computer science."


The same way language is necessary for philosophy. But we discuss language elsewhere. Linguistics forum for example.

A more pointless thread i have not seen. Surprised it hasn't been rubbished to some appropriate forum still.

Don't knock it. Apparently, a heated debate might break out at any minute. Then, we can all dive in.

... Ad homs, cheerleading, nonsensical rhetoric, barracking. We'll soon have a philosophy thread. Just give it time.
Il messaggero non e importante.
Ora non e importante.
Il resultato futuro e importante.
Quindi, persisto.
jamest
 
Posts: 17737
Male

Country: England
Jolly Roger (arr)
Print view this post

Ads by Google


Re: Programming

#62  Postby VazScep » Mar 12, 2012 5:49 pm

mizvekov wrote:Yes. I came to use Fusion because of another boost lib, called Spirit, which is basically a Scanner / Parser library.
With it, you can very seamlessly create a parser from a BNF grammar, and have it generate an AST from the input with very little effort. It will normally build this AST from stl containers (or their boost equivalents) and tuples. And here Fusion helps because then you can use your own custom structs instead of tuples.
That's awesome. Even though they're such a simple concept, tuples are something I miss immediately when I go back to Java and C#.

VazScep wrote:Well it does get used implicitly in the cases where this would have no user visible effects, such as any assignment which would obliterate the original value anyway.
Or it can be used explicitly with std::move. In this case, you would be exposed to the original 'moved from' object.
There isn't much in the way of guarantees of in what state this object will be, except that they must be in a destructible state, ie the destructor will not segfault when it is called. Everything else is up to whoever implements the class to define what happens. But the STL classes are guaranteed by the standard to be left in sensible states, so for example a moved vector will be left in an empty state.
So as it is up to whoever implements it to define, you as a user at least will have the guarantee that the 'moved to' object will be in the intended state. You can assume that whoever wrote the class you are using either did not provide a move constructor or provided one which works.
Ugh. I misread you and thought the move semantics was something particular to lambda expressions. I think it makes sense now!

VazScep wrote:Well that depends on what you mean by "destructive member".
You can easily see what happens in the lambda case if you think about it's equivalent Functor.
So for example if you have this lambda:
Code: Select all
[b]() { b.destructive_method(); }

It's equivalent Functor will be something like:
Code: Select all
struct Lambda {
    const B b;
    Lambda(B &b_) : b(b_) {}
    void operator()() { b.destructive_method(); }
};

Whereas if you had:
Code: Select all
[b]() mutable { b.destructive_method(); }

The equivalent one is:
Code: Select all
struct Lambda {
    B b;
    Lambda(B &b_) : b(b_) {}
    void operator()() { b.destructive_method(); }
};

Notice how the constness of b differs between these two.

Now, if you had B defined as something like this:
Code: Select all
struct B {
      int val;
      void b.destructive_method() { val = 0; }
};


The first lambda example and it's equivalent Functor would both fail to compile, because destructive_method is not a "const" method.
What happens here is basically that methods in a class take a hidden parameter that is passed implicitly, called the 'this' parameter.
It is as if you had the below in C:
Code: Select all
void destructive_method(struct B *this) { this->val = 0; }

And when you try to call it by passing a const pointer to the 'this' parameter, it fails to compile because the parameters type cannot be implicitly casted.
You can fix it by doing the below instead:
Code: Select all
void b.destructive_method() const { val = 0; }

which is equivalent to:
Code: Select all
void destructive_method(const struct B *this) { this->val = 0; }

And then it will continue compilation, but fail again on "val = 0", because it will try to do "this->val = 0;" with 'this' being a const pointer, which is not allowed.
But the question then becomes, can this method be destructive even if it's pointer to it's own instance is const?
The answer is absofuckinglutelly yes, that method still has access to global data, which can be and is usually declared as non-const, it can still call OS APIs and such.
And it can even do something evil like:
Code: Select all
void b.destructive_method() const { const_cast<B*>(this)->val = 0; }

So anyway, it is up to whoever writes the class to decide what happens, and if that person wants to be a raving lunatic, the type system will not stop him.
But in general, no sane library will do something like this.
Great stuff! Cheers for the explanation. I had a feeling it had something to do with constness, which is another thing that I think C++ gets right compared to its "successors". Of course, since I started functional programming, my attitude has been towards const and immutability by default :grin:

Okay great, much better, anyway thank you again, I will try playing with it a little.
You'll find it a real pain to do any proofs. The biggest headache is the fact that you can't write things like:

Code: Select all
1) P  (assumption)
2) P => Q  (assumption)
3) Q  (MP 1,2)
4) P => (P => Q) => Q (1-3)


There's just nothing in the formal system which allows you to make assumptions like this and then discharge them at the end of a proof. And yet being able to do this makes things so much easier.

So the first thing you encounter in the proof theory of this sort of formal system is the "Deduction Theorem", which shows that any proof with explicit assumptions can always be translated into a proof which doesn't make explicit assumptions. And after writing my utilities module, the first thing I did was define a new proof language which allows for explicit assumptions, and then I wrote a "Deduction Function", which mirrors the Deduction Theorem exactly except that it is recursive where the theorem is inductive. This function transforms a proof in the new proof language into a true theorem from the logical kernel.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Programming

#63  Postby stalidon » Mar 12, 2012 6:30 pm

Jumbo wrote:
Of course everyone knows Allman style is the only sensible method but some people don't like to admit it! :whistle:


Indeedly, and you must have brackets even if the code-block is empty, or it's a one-liner! I'm kindling the fire for anyone that challenges this absolute truth.
-
stalidon
 
Posts: 145
Age: 45
Male

Country: Argentina
Argentina (ar)
Print view this post

Re: Programming

#64  Postby VazScep » Mar 12, 2012 6:51 pm

stalidon wrote:
Jumbo wrote:
Of course everyone knows Allman style is the only sensible method but some people don't like to admit it! :whistle:


Indeedly, and you must have brackets even if the code-block is empty, or it's a one-liner! I'm kindling the fire for anyone that challenges this absolute truth.
As a recovering Lisp hacker, I sometimes wake up thinking that this syntax stuff was a mistake to begin with and that we should just be writing our code in the form of its own parse tree.

There are good reasons why you would want to do this. Lisp programmers are not, as legend would have it, total idiots who like their code to be as fugly as possible.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Programming

#65  Postby stalidon » Mar 12, 2012 6:55 pm

VazScep wrote:
stalidon wrote:
Jumbo wrote:
Of course everyone knows Allman style is the only sensible method but some people don't like to admit it! :whistle:


Indeedly, and you must have brackets even if the code-block is empty, or it's a one-liner! I'm kindling the fire for anyone that challenges this absolute truth.
As a recovering Lisp hacker, I sometimes wake up thinking that this syntax stuff was a mistake to begin with and that we should just be writing our code in the form of its own parse tree.


You're just rationalizing your nightmares as something 'you thought'. For crying out loud, where would readability go if we started writing code in ASTs... where would the brackets go??
-
stalidon
 
Posts: 145
Age: 45
Male

Country: Argentina
Argentina (ar)
Print view this post

Re: Programming

#66  Postby epepke » Mar 12, 2012 8:26 pm

VazScep wrote:As a recovering Lisp hacker, I sometimes wake up thinking that this syntax stuff was a mistake to begin with and that we should just be writing our code in the form of its own parse tree.

Image
User avatar
epepke
 
Posts: 4080

Country: US
United States (us)
Print view this post

Re: Programming

#67  Postby VazScep » Mar 12, 2012 8:54 pm

I was taught assembler
in my second year of school.
It's kinda like construction work --
with a toothpick for a tool.
So when I made my senior year,
I threw my code away,
And learned the way to program
that I still prefer today.

Now, some folks on the Internet
put their faith in C++.
They swear that it's so powerful,
it's what God used for us.
And maybe it lets mortals dredge
their objects from the C.
But I think that explains
why only God can make a tree.

For God wrote in Lisp code
When he filled the leaves with green.
The fractal flowers and recursive roots:
The most lovely hack I've seen.
And when I ponder snowflakes,
never finding two the same,
I know God likes a language
with its own four-letter name.

Now, I've used a SUN under Unix,
so I've seen what C can hold.
I've surfed for Perls, found what Fortran's for,
Got that Java stuff down cold.
Though the chance that I'd write COBOL code
is a SNOBOL's chance in Hell.
And I basically hate hieroglyphs,
so I won't use APL.

Now, God must know all these languages,
and a few I haven't named.
But the Lord made sure, when each sparrow falls,
that its flesh will be reclaimed.
And the Lord could not count grains of sand
with a 32-bit word.
Who knows where we would go to
if Lisp weren't what he preferred?

And God wrote in Lisp code
Every creature great and small.
Don't search the disk drive for man.c,
When the listing's on the wall.
And when I watch the lightning burn
Unbelievers to a crisp,
I know God had six days to work,
So he wrote it all in Lisp.

Yes, God had a deadline.
So he wrote it all in Lisp.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Ads by Google


Re: Programming

#68  Postby mizvekov » Mar 12, 2012 9:28 pm

VazScep wrote:You'll find it a real pain to do any proofs. The biggest headache is the fact that you can't write things like:

Code: Select all
1) P  (assumption)
2) P => Q  (assumption)
3) Q  (MP 1,2)
4) P => (P => Q) => Q (1-3)


There's just nothing in the formal system which allows you to make assumptions like this and then discharge them at the end of a proof. And yet being able to do this makes things so much easier.

So the first thing you encounter in the proof theory of this sort of formal system is the "Deduction Theorem", which shows that any proof with explicit assumptions can always be translated into a proof which doesn't make explicit assumptions. And after writing my utilities module, the first thing I did was define a new proof language which allows for explicit assumptions, and then I wrote a "Deduction Function", which mirrors the Deduction Theorem exactly except that it is recursive where the theorem is inductive. This function transforms a proof in the new proof language into a true theorem from the logical kernel.

I see, thanks for the explanation.
I have one question though, is it of any utility here to do something like this:
Code: Select all
inst (\v -> if v == "p" then (theoremTerm (inst (\v -> Var v) axiom3)) else Var "b") axiom1

Ie getting the term of a theorem (using theoremTerm) and then using that to instantiate another axiom?
mizvekov
 
Posts: 314
Age: 35
Male

Brazil (br)
Print view this post

Re: Programming

#69  Postby mizvekov » Mar 12, 2012 9:34 pm

VazScep wrote:I was taught assembler
in my second year of school.
It's kinda like construction work --
with a toothpick for a tool.
So when I made my senior year,
I threw my code away,
And learned the way to program
that I still prefer today.
....

Hahaha cool, did you write that?
mizvekov
 
Posts: 314
Age: 35
Male

Brazil (br)
Print view this post

Re: Programming

#70  Postby stalidon » Mar 13, 2012 12:50 am

Okay, where can I download this Lisp thing for Win32? :p
-
stalidon
 
Posts: 145
Age: 45
Male

Country: Argentina
Argentina (ar)
Print view this post

Re: Programming

#71  Postby mizvekov » Mar 13, 2012 1:02 am

stalidon wrote:Okay, where can I download this Lisp thing for Win32? :p

You would be looking for some of the LISP variants :)
VazScep said he used to like Common Lisp before being introduced to strongly typed functional languages, like ML variants and Haskell.
You can get what appears to be a well appreciated implementation here: http://www.clisp.org/
I never used it myself, instead I dabbled with another variant called Scheme years ago in a Uni class.
You can get a free implementation here: http://www.gnu.org/software/mit-scheme/

But these logic examples we have been talking about is not LISP, but another language called Haskell.
You download it here: http://hackage.haskell.org/platform/
mizvekov
 
Posts: 314
Age: 35
Male

Brazil (br)
Print view this post

Re: Programming

#72  Postby stalidon » Mar 13, 2012 1:14 am

Yeah, Lisp has a long-lasting heritage... and since I started programming in the 80s Lisp was on my 'to check' list...

Would Scheme or Haskell give me a taste of Lisp's paradigm? That is, are any of them an 'upgrade' on common Lisp, or different paradigms altogether?
-
stalidon
 
Posts: 145
Age: 45
Male

Country: Argentina
Argentina (ar)
Print view this post

Re: Programming

#73  Postby mizvekov » Mar 13, 2012 1:20 am

stalidon wrote:Yeah, Lisp has a long-lasting heritage... and since I started programming in the 80s Lisp was on my 'to check' list...

Would Scheme or Haskell give me a taste of Lisp's paradigm? That is, are any of them an 'upgrade' on common Lisp, or different paradigms altogether?

Scheme is another LISP variant, so if you want to start from the basics, I don't think you will see much of a difference.
It seems much more limited though if you want to do systems programming with it.

Haskell is another beast altogether... Although it has a small amount of similarities, it's by far not enough so that a LISPer could start hacking on it without reading a book or something.
mizvekov
 
Posts: 314
Age: 35
Male

Brazil (br)
Print view this post

Re: Programming

#74  Postby stalidon » Mar 13, 2012 1:26 am

:thumbup:

Thanks for the links!
-
stalidon
 
Posts: 145
Age: 45
Male

Country: Argentina
Argentina (ar)
Print view this post

Re: Programming

#75  Postby mizvekov » Mar 13, 2012 2:19 am

Cito di Pense wrote:I have hope again! Qt makes me feel dirty. Somebody owns it, which is the way it is for so much c++. Nobody pwns it.

Well, I have been more interested in wxWidgets lately. You should check it out, if you haven't done so. Better license, and less uncertain future.
mizvekov
 
Posts: 314
Age: 35
Male

Brazil (br)
Print view this post

Ads by Google


Re: Programming

#76  Postby VazScep » Mar 13, 2012 8:36 am

Full disclosure: I got into a drunken and somewhat heated debate last night on the rough premise "The human brain is not designed to be able to read Lisp". I argued the negative.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Programming

#77  Postby VazScep » Mar 13, 2012 8:48 am

mizvekov wrote:I have one question though, is it of any utility here to do something like this:
Code: Select all
inst (\v -> if v == "p" then (theoremTerm (inst (\v -> Var v) axiom3)) else Var "b") axiom1

Ie getting the term of a theorem (using theoremTerm) and then using that to instantiate another axiom?
Note that
Code: Select all
inst (\v -> Var v)
is just the identity.

It wouldn't surprise me if "inst" turned out to be useful. In this style of theorem prover, there is a lot of bootstrapping. You build a load of machinery on top of the kernel and then completely forget about the basic inference rules. This doesn't mean that the inference rules are useless. It just means that I haven't played with them much!

Hahaha cool, did you write that?
Oh, I wish! I think it appeared on the FSF mailing list at one time.
Last edited by VazScep on Mar 13, 2012 9:41 am, edited 1 time in total.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Programming

#78  Postby mizvekov » Mar 13, 2012 9:15 am

Full disclosure: I got into a drunken and somewhat heated debate last night on the rough premise "The human brain is not designed to be able to read Lisp"

That premise is worded quite strongly, but I can't really disagree with a weaker version of it.
It's quite difficult to match all those pesky parentheses to their closing ones :smile:
On a more serious note, I think LISP underutilizes our ability to remember lots os symbols and to map names to things, while it abuses our capacity to keep track of nesting.
I think one of the nicest things of ML-like languages is to finally get rid of bracket hell, and balance better those things I said.

Hope I am not starting a flamewar here :grin:
mizvekov
 
Posts: 314
Age: 35
Male

Brazil (br)
Print view this post

Re: Programming

#79  Postby VazScep » Mar 13, 2012 9:38 am

stalidon wrote:Yeah, Lisp has a long-lasting heritage... and since I started programming in the 80s Lisp was on my 'to check' list...

Would Scheme or Haskell give me a taste of Lisp's paradigm? That is, are any of them an 'upgrade' on common Lisp, or different paradigms altogether?
I wouldn't learn Haskell if you want to learn Lisp. Some people would say that Haskell is an upgraded Lisp, but I don't much care for the view. The Lisp attitude with regards to typing is completely polar opposite to Haskell, and there are a lot of ideas that Haskell threw out of the Lisp view of the world, including the sole thing that makes Lisp unique among all languages: code is data.

Don't worry about finding an "upgrade" to Common Lisp. Common Lisp was built on a philosophy beautifully explained here. It's designed to do the "right thing" all over the place, making it an extremely powerful language at the expense of making it extremely difficult to write a conforming implementation. One reason there are no upgrades to Common Lisp is because they are a nightmare to implement efficiently (as the essay explains, this is also the reason why we haven't really upgraded from UNIX).

That is why there are a great many interesting ideas implemented in Common Lisp that I have never seen implemented anywhere else. I am happy to be corrected, but I have never used any other language whose debugger compares: when you hit a runtime exception in Common Lisp, you are given a stack-trace and you enter a debug loop. Here, you can navigate up and down the stack-frame, inspect the arguments passed to all of the functions in the stack frame, and ask Lisp to try rerunning any of those functions but with new arguments computed from arbitrary Lisp code. You can generally write arbitrary Lisp code in the debug loop. So you can happily rewrite the source code of an offending function, recompile that function from the debug loop (in Lisp, you have access to the compiler at runtime via the ordinary Lisp function "compile") or rebind offending global variables, and then continue execution or retry execution from any part of the stack frame as if nothing had ever gone wrong. There are great stories of shipped Lisp systems, which, when they crashed, the developer would simply ssh into the machine, fix the bug at the stack-trace, and then let the system carry on business-as-usual as if there had been no downtime. (Admittedly, Smalltalk does this sort of thing even better, but that's why Smalltalk is sometimes called a Lisp).

When I first started learning Python, I remember doing some extensive testing at the toplevel, creating a whole bunch of instances of my various classes and putting them together. I then fixed a bug in a class definition, by redefining one of its methods, and then reloaded the code at the toplevel. I was surprised to find that none of the instances I had previously created had the new method.

Python programmers pointed out to me that this was to be expected, that only new instances would respect the class redefinition. This attitude is itself to be expected from a bunch of people who have such low expectations from their technology that they think Python is an achievement, and not just a poor man's Smalltalk. It is worse-is-better. The right thing is what Common Lisp does: it tells every instance to bring itself up to date with the new class definition, a procedure that is compounded in its righteousness by the fact that the behaviour can be customised by specialising "reinitialize-instance" with your own metaobjects. Like I say, Common Lisp is a bastard in its complexity, but a delight for its users.

If you want a Lisp, Common Lisp is the most Lispy Lisp there is.

For a Win32 implementation, use CLISP, because it's free. You can also use Corman Lisp which has a 30-day trial.

Generally, you're better off on Linux. In fact, the only reason I started using Linux and Emacs in the first place was because I was getting into Lisp.

This is just if you're curious about the Lisp heritage and want to see some cool ideas. Alternatively, if you want to use a Lisp in the 21st century, check out Clojure. For a relatively new language, Clojure has totally taken off, competing head-on with Scala to be the language for the Java virtual machine. It's also a pretty damn Lispy Lisp, keeping many of the ideas that makes Common Lisp great, adding in some ideas from ML-style functional programming (such as ML style references, software transactional memory, agent-based concurrency, and an emphasis on immutability) and throwing out all the crud that made Common Lisp stupid (such as separate namespaces for variables and functions).
Last edited by VazScep on Mar 13, 2012 10:26 am, edited 5 times in total.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Programming

#80  Postby VazScep » Mar 13, 2012 9:51 am

mizvekov wrote:That premise is worded quite strongly, but I can't really disagree with a weaker version of it.
It's quite difficult to match all those pesky parentheses to their closing ones :smile:
I just never really bought that. For starters, no serious Lisp user would dream of Lisp hacking without a facility to highlight matching parentheses. (go to Options->Paren Match Highlighting in Emacs). And with decent syntax highlighting and appropriate indentation, I never found readability an issue in Lisp. That's not cheating: every language cares about appropriate indentation and syntax highlighting, and I always have paren-match highlighting turned on when hacking in ML or Haskell.

In fact, when I'm tallying my shopping lists or budgeting, I tend to use Lisp so that I can write in this style:

Code: Select all
(+ (* 2 37) ; beans
    400      ;detergent
    127      ; meat
    1000    ; extremely expensive cuisine that helps make this look less of a student's shopping list
)


and because of Lisp's syntax, I can put my cursor at the end of subexpressions such as (* 2 37) and evaluate just that part by hitting C-x C-e.

This is probably not much of an argument. I am, after all, stupid enough to think that Emacs and xmonad make me substantially more productive than someone using the latest gimmicks from Apple.

On a more serious note, I think LISP underutilizes our ability to remember lots os symbols and to map names to things, while it abuses our capacity to keep track of nesting.
Well, that's the sort of argument I was up against. The problem is that it, even as someone who has ditched Lisp and never looked back, this doesn't match my experience at all. I just never had the sort of problems people complain about, and so my suspicion is that the complaints can be explained in other ways (such as a simple case of not getting used to it). On the other hand, I don't see any empirical evidence (or any clue how you would reliably gather it) that Lisp really is difficult for humans to read.

It is also worth mentioning that John McCarthy never intended Lisp programmers to write s-expressions directly. The s-expressions were supposed to just represent the parse trees, and an alternative m-expression syntax would be built over the top. In questioning Lisp's design choice here, it is always worth remembering that when given the choice, the Lisp users favoured the s-expressions over the m-expressions, and so the m-expression syntax was forever scrapped.

Hope I am not starting a flamewar here :grin:
So long as I'm sober, I can probably keep my emotions under control :drunk:
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

PreviousNext

Return to Philosophy

Who is online

Users viewing this topic: No registered users and 1 guest