Programming

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

Moderators: kiore, The_Metatron, Blip

Programming

#1  Postby VazScep » Mar 07, 2012 11:43 am


!
GENERAL MODNOTE
Thread split from here by request. -Spinozasgalt
SpeedOfSound wrote:I discovered a new set of tinker toys.

About a year ago I ran into a serious issue with NS that is only hinted at by your mention of models above. Up against a mathematical wall and looking for a way in.
In computer science, we talk about abstract data-types rather than abstract algebras, and we talk about implementations rather than models. They amount to the same thing. In theorem proving, we use precisely the same syntactic machinery to define group theory and its models as we do to define say, the abstract data-type of sets and its implementations.

You need quite a bit of extra machinery to pull this sort of thing off and get it type-checked. In Java, you can define interfaces for your abstract types and define classes implementing those interfaces for the models. In C++, you use the keyword "abstract" explicitly for the interfaces. In ML, you have signatures and structures. If you don't have these extra bits of machinery, you are shit out of luck.

But one thing you do have in some of these languages is type-polymorphism. In Java and C#, this is called "generics". And it's pretty powerful.

I encountered a blog last year which has the snappy title "Abstract types are existential types!" I didn't read the blog at the time. The title was beautiful enough. It was declaring that when we talk in abstractions, as in abstract algebra, we are really just talking in existentials. To say that something exists is to form an abstraction and to form an abstraction is just to say that something exists.

It's basically a cool play on words. After reading it, I went ahead and used the standard intuitionistic encoding of existential quantifiers by the universal quantifier, used the fact that universal quantifiers are effectively type-polymorhism, and, using the play on words that abstraction is existence, I wrote the following program which encodes the expressive power of structure/signature and interface/implementation using rank-n type-polymorphism.

Code: Select all
{-# LANGUAGE RankNTypes, ImpredicativeTypes, ScopedTypeVariables #-}

import qualified Data.Set as S
import Data.List (insert)

-- The type of first-class abstract collections.
-- The basic idea is that abstract types have existential type, and
-- with the right extensions, "exists x. p" can be rendered as
-- "(forall a. p -> r) -> r." In this case, p is a tuple (or record)
-- containing the particular implementation of a collection. This
-- implementation is thrown to a continuation which must generalise
-- over the abstract type a. For this, we need at least rank-2
-- polymorphism, and it has to be impredicative for some reason.
-- Notice also that the type has higher-order kind, since type a has
-- kind * -> *.
type Collection r
  = ( forall a. ( forall b. Ord b => a b
                , forall b. Ord b => b -> a b -> a b
                , forall b. Ord b => a b -> [b])      -> r) -> r

list :: Collection r
list k = k ([], (:), id)

set :: Collection r
set k = k (S.empty, S.insert, S.elems)

bag :: Collection r
bag k = k ([], insert, id)

-- Silly example, pushing two lists through a collection type.
viaCollection :: (Ord a,Ord b)
                   => Collection ([a],[b]) -> ([a],[b]) -> ([a],[b])
viaCollection c (xs,ys) = c f
  where f (empty  :: forall b. Ord b => a b
          ,insert :: forall b. Ord b => b -> a b -> a b
          ,elems  :: forall b. Ord b => a b -> [b])
          = (elems $ foldr insert empty xs,
             elems $ foldr insert empty ys)
None of this is new (well, it was new to me). But it's the sort of application of a play on words that I can get behind, and, referencing the other thread, it's the sort of thing which makes me suspect that the incestuous relationship that logic has with computer science has spawned far cooler things than the incestuous relationship logic has had with philosophy.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Truth is relative: why do we criticize religion?

#2  Postby SpeedOfSound » Mar 07, 2012 11:54 am

I think logic has the same relationship to philosophy as the popular abuse of cat's in QM has to physics. I would describe it as pathetic and very disappointing.

Vaz, That's some cool shit. I need to look into this.

What language is that? Got link?
User avatar
SpeedOfSound
RS Donator
 
Posts: 32086
Age: 70
Male

Kyrgyzstan (kg)
Print view this post

Re: Truth is relative: why do we criticize religion?

#3  Postby VazScep » Mar 07, 2012 12:05 pm

SpeedOfSound wrote:What language is that? Got link?
You can get hold of it here.

Haskell Platform

And here are two free online books: Learn you a Haskell for Great Good! and Real World Haskell.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Truth is relative: why do we criticize religion?

#4  Postby mizvekov » Mar 07, 2012 1:13 pm

Just a minor nitpick here: C++ doesnt actually have an abstract keyword, that seems to be an extension specific to microsoft visual studio .NET / CLI
The common pattern to having interfaces in standard c++ is declaring classes with only pure virtual functions.
Eg.
virtual void foo() = 0;
mizvekov
 
Posts: 314
Age: 37
Male

Brazil (br)
Print view this post

Re: Truth is relative: why do we criticize religion?

#5  Postby VazScep » Mar 07, 2012 1:20 pm

mizvekov wrote:Just a minor nitpick here: C++ doesnt actually have an abstract keyword, that seems to be an extension specific to microsoft visual studio .NET / CLI
The common pattern to having interfaces in standard c++ is declaring classes with only pure virtual functions.
Eg.
virtual void foo() = 0;
Ah yes. It's been a long time since I've coded in C++.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Truth is relative: why do we criticize religion?

#6  Postby mizvekov » Mar 07, 2012 1:41 pm

VazScep wrote:Ah yes. It's been a long time since I've coded in C++.

It's worth noting that the language has gotten much better with the latest standard, and it deserves a new look at.
But it seems you left it for a higher plane of existance. Been learning Haskell myself too, but that hasn't been going too fast because I could never bring myself to justify using it for (paid) work.
mizvekov
 
Posts: 314
Age: 37
Male

Brazil (br)
Print view this post

Re: Truth is relative: why do we criticize religion?

#7  Postby VazScep » Mar 07, 2012 1:53 pm

mizvekov wrote:
VazScep wrote:Ah yes. It's been a long time since I've coded in C++.

It's worth noting that the language has gotten much better with the latest standard, and it deserves a new look at.

But it seems you left it for a higher plane of existance. Been learning Haskell myself too, but that hasn't been going too fast because I could never bring myself to justify using it for (paid) work.
If I don't get a post-doc position, I'm planning to go into industry. There's work out there using strongly typed functional languages (a friend of mine codes in Ocaml for a living, which would be awesome).

But I wouldn't say I've left the C++ world forever. I'm pretty confident that I'd still have fun being a C++/Java/C# programmer, and I'm pretty sure I could get excited about learning C++ properly, with all the Boost libraries, and any cool shit that's in the latest standard. There's also C#, though, which takes a lot of inspiration from the functional world and from Haskell (LINQ is just monads underneath).

I actually left C++, Java and C# behind when I discovered languages in the Lisp family (Smalltalk and Common Lisp in particular) and I came to the conclusion that static typing was stupid. Then about a year into my phd I discovered the ML family of languages, and I'm now pretty obsessed with types. I think now I'd rather code in C++ than I would in an untyped language.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Truth is relative: why do we criticize religion?

#8  Postby mizvekov » Mar 07, 2012 8:43 pm

VazScep wrote:If I don't get a post-doc position, I'm planning to go into industry. There's work out there using strongly typed functional languages (a friend of mine codes in Ocaml for a living, which would be awesome).

I don't doubt that, it's just that I have been working a lot with embedded lately, and I am mostly using C / subset of C++, sometimes even assembly, because code size often matters (sometimes only a few kb of flash).
VazScep wrote:
But I wouldn't say I've left the C++ world forever. I'm pretty confident that I'd still have fun being a C++/Java/C# programmer, and I'm pretty sure I could get excited about learning C++ properly, with all the Boost libraries, and any cool shit that's in the latest standard. There's also C#, though, which takes a lot of inspiration from the functional world and from Haskell (LINQ is just monads underneath).

There is also SCALA, which has many similarities to Haskell, but also has a more familiar syntax and java interoperability, so I think it has much more potential for industry acceptance.
VazScep wrote:
I actually left C++, Java and C# behind when I discovered languages in the Lisp family (Smalltalk and Common Lisp in particular) and I came to the conclusion that static typing was stupid. Then about a year into my phd I discovered the ML family of languages, and I'm now pretty obsessed with types. I think now I'd rather code in C++ than I would in an untyped language.

I was pretty obsessed with emulators starting when I was a teen, and when I first learned LISP when I was in college, I looked down on it, probably because it felt less expressive, I was more concerned with runtime performance than I should, and also because it was less widely used/less appropriate for the kind of problems that I was concerned about.
It took learning a bit about lambda calculus to start liking it, and also learning how easy (formulaic) it is to translate algorithms from iterative to recursive.

I agree about the Haskell type system, I think it is amazing how cleanly It can express complex things. Function types in particular, it's too cool that you can do things like partial application just naturally, and it all ties together perfectly.

Modern c++ has some of these new things, but the syntax for it is clunky, the type system a lot less expressive, and it still suffers from some of the same old flaws, like incomprehensible compiler error messages.
mizvekov
 
Posts: 314
Age: 37
Male

Brazil (br)
Print view this post

Re: Truth is relative: why do we criticize religion?

#9  Postby VazScep » Mar 07, 2012 9:25 pm

mizvekov wrote:I don't doubt that, it's just that I have been working a lot with embedded lately, and I am mostly using C / subset of C++, sometimes even assembly, because code size often matters (sometimes only a few kb of flash).
Ah. Yeah. When you have to lug around 10Mb of runtime, you've got a non-starter there. Are things like tinyscheme workable?

VazScep wrote:There is also SCALA, which has many similarities to Haskell, but also has a more familiar syntax and java interoperability, so I think it has much more potential for industry acceptance.
Ack. I worked with Scala for about a month and didn't enjoy a second of it. There's not enough type-inference for my tastes, I found it very verbose, and I think supporting null values is a big mistake (Tony Hoare calls his invention of the null value his "billion dollar mistake"). I'm much more hopeful about F#, which has made far fewer concessions to the OO world and looks far more like an ML dialect. The integration of type-inference into Visual Studio's intellisense makes it a joy to program with, and type inferred units of measure are just awesome.

VazScep wrote:I was pretty obsessed with emulators starting when I was a teen, and when I first learned LISP when I was in college, I looked down on it, probably because it felt less expressive, I was more concerned with runtime performance than I should, and also because it was less widely used/less appropriate for the kind of problems that I was concerned about.
Can I ask which Lisp dialect you were using? If it makes sense to say, I find Common Lisp far too powerful.

Modern c++ has some of these new things, but the syntax for it is clunky, the type system a lot less expressive, and it still suffers from some of the same old flaws, like incomprehensible compiler error messages.
I've seen bits of the syntax for partial application with boost::lambda. It looked pretty line-noisy.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Truth is relative: why do we criticize religion?

#10  Postby mizvekov » Mar 08, 2012 3:01 am

VazScep wrote:Ah. Yeah. When you have to lug around 10Mb of runtime, you've got a non-starter there. Are things like tinyscheme workable?
Yes, I guess so, but I have not worked on a project yet where it would make sense.
Also, If I could use tinyscheme, I probably could use LUA, which has a more familiar syntax to those coming from imperative languages.

VazScep wrote:Ack. I worked with Scala for about a month and didn't enjoy a second of it. There's not enough type-inference for my tastes, I found it very verbose, and I think supporting null values is a big mistake (Tony Hoare calls his invention of the null value his "billion dollar mistake"). I'm much more hopeful about F#, which has made far fewer concessions to the OO world and looks far more like an ML dialect. The integration of type-inference into Visual Studio's intellisense makes it a joy to program with, and type inferred units of measure are just awesome.

I see, will keep that in mind next time I am up for learning it. Note however that none of this precludes it from having industry acceptance, there is far worse around :grin:

VazScep wrote:I've seen bits of the syntax for partial application with boost::lambda. It looked pretty line-noisy.

Yeah, but boost::lambda is pretty overkill for that, it's meant to provide lambda function support to c++98 compilers, and it is pretty hackish at that. No wonder it did not get accepted into c++11, and we got instead a proper lambda support which allows you to write their body just like any other function.
For partial function application, you could use boost::bind, which has been accepted into the standard as std::bind.
The syntax looks something like:
Code: Select all
        int b = 10;
        auto foo = [b](int a) -> int { return a + b; };
        auto bar = std::bind(foo, 1);
        std::cout << foo(2) << ' ' << bar() << std::endl;

This will print "12 11".
The example also shows the use of c++11 lambdas in the second line (declares a lambda which takes an int, returns an int, and captures variable b by value).
This also shows type inference with the repurposed "auto" keyword (it meant automatic allocation previously, as taken from C, but it was the default for every place which you could use it, so you never really had to use this keyword before, could leave it implicit).
The auto keyword is necessary in the lambda case because there is no way to express the type of a lambda which captures any variables. Lambdas that do not capture any variables are typed just like an ordinary function pointer.
Note also that std::bind can do parameter reordering as well.
Code: Select all
       auto foo = [](int a, int b) -> int { return a - b; };
       using namespace std::placeholders;
       auto bar = std::bind(foo, _2, _1); //Now you have foo with parameters reordered


By the way, do you have any recommended literature for Haskell beyond the beginner books?
mizvekov
 
Posts: 314
Age: 37
Male

Brazil (br)
Print view this post

Re: Truth is relative: why do we criticize religion?

#11  Postby mizvekov » Mar 08, 2012 3:13 am

Forgot to reply to this bit:

VazScep wrote:Can I ask which Lisp dialect you were using? If it makes sense to say, I find Common Lisp far too powerful.

Sure, I have no problem answering any questions.
I was using scheme actually, and perhaps only a subset of it.
At the time it felt pretty limiting, because it is hard to express state changes. I didn't learn anything about monads until much later.
mizvekov
 
Posts: 314
Age: 37
Male

Brazil (br)
Print view this post

Re: Truth is relative: why do we criticize religion?

#12  Postby VazScep » Mar 08, 2012 11:19 am

mizvekov wrote:Yeah, but boost::lambda is pretty overkill for that, it's meant to provide lambda function support to c++98 compilers, and it is pretty hackish at that. No wonder it did not get accepted into c++11, and we got instead a proper lambda support which allows you to write their body just like any other function.
For partial function application, you could use boost::bind, which has been accepted into the standard as std::bind.
The syntax looks something like:
Code: Select all
        int b = 10;
        auto foo = [b](int a) -> int { return a + b; };
        auto bar = std::bind(foo, 1);
        std::cout << foo(2) << ' ' << bar() << std::endl;

This will print "12 11".
Oohh...this is new.

So here's the question: suppose b is a pointer to a dynamically allocated object, and this code appears in a function where the lambda foo is returned. How does the memory management work out? Are there useful smart pointers to deal with it?

By the way, do you have any recommended literature for Haskell beyond the beginner books?
I think the latter chapters in "School of Expression" are worth a read, especially the stuff on reactive programming. Other than that, there's Haskellwiki, which has articles on more advanced stuff like monad transformers and arrows. After that, I guess it's just research papers. When I was getting interested in Software Transactional Memory back in 2006, I was having to read Peyton-Jones' (very nicely-written) research papers.

I was using scheme actually, and perhaps only a subset of it.
At the time it felt pretty limiting, because it is hard to express state changes. I didn't learn anything about monads until much later.
Does it not have variable assignment and update and globals?

I've never used Scheme. Common Lisp on the other hand allows for the nastiest side-effects you can imagine. The components of any cons-cell can be mutated, so you can be handed a list, make a destructive modification on it, and find that you've radically altered data structures all over the place which happened to share parts of the original list. And this is before we getting into rebinding function symbols on the fly or making changes to the dispatch mechanism of functions. :ill:

Though I'm a little sceptical about using monads or any combinator language in an untyped language. The first serious combinator languages that I'm aware of came from ML, and one of the main guys in the ML community back then stressed that "tactic" combinators were only possible when you had a type system for higher-order functions. Often, when I'm working with monads and monad transformers, I'm not really thinking about code or thinking about what a function does. It's too abstract for me by that point. I get by just thinking entirely at the level of types. And I really don't want my frequent mistakes to show up as runtime exceptions. Given the heavy dosage of lambdas involved, I expect most of those exceptions to be thrown from closures a good distance away from the original error.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Truth is relative: why do we criticize religion?

#13  Postby mizvekov » Mar 08, 2012 8:26 pm

VazScep wrote:Oohh...this is new.

So here's the question: suppose b is a pointer to a dynamically allocated object, and this code appears in a function where the lambda foo is returned. How does the memory management work out? Are there useful smart pointers to deal with it?

Yes, there are a few additions to the standard, that came from boost, that will help here.
You can start by using std::shared_ptr, which is a reference counted pointer container, that will delete automatically when the count reaches 0.
Code: Select all
struct B {
        int val;
        B(int v) : val(v) {}
        ~B() { std::cout << "bye " << val << std::endl; }
};

std::function<int(int)> f(std::shared_ptr<B> b) {
        return [b](int a) -> int { return a + b->val; };
}

std::function<int(int)> g() {
        auto a = std::make_shared<B>(10), b = std::make_shared<B>(20);
        return f(a);
}
int main() {
        {
                auto foo = g();
                auto bar = std::bind(foo, 1);
                std::cout << foo(2) << ' ' << bar() << std::endl;
        }
        std::cout << "the end" << std::endl;
}

This will print
Code: Select all
bye 20
12 11
bye 10
the end

I am also using std::function there too, which is a polymorphic wrapper for any callable type.

I think the latter chapters in "School of Expression" are worth a read, especially the stuff on reactive programming. Other than that, there's Haskellwiki, which has articles on more advanced stuff like monad transformers and arrows. After that, I guess it's just research papers. When I was getting interested in Software Transactional Memory back in 2006, I was having to read Peyton-Jones' (very nicely-written) research papers.

I see, thanks!

Does it not have variable assignment and update and globals?

At least they never introduced it to us, so like I said, it was a pretty limiting experience. It was like programming with both hands tied. I would be given a problem, then solve it almost instantly in my head, but then take a long time translating that into a pretty constrained language.

I've never used Scheme. Common Lisp on the other hand allows for the nastiest side-effects you can imagine. The components of any cons-cell can be mutated, so you can be handed a list, make a destructive modification on it, and find that you've radically altered data structures all over the place which happened to share parts of the original list. And this is before we getting into rebinding function symbols on the fly or making changes to the dispatch mechanism of functions. :ill:

Wow, I misjudged the LISP guys, I thought they would find something like that an aberration and kill it with fire.

Though I'm a little sceptical about using monads or any combinator language in an untyped language. The first serious combinator languages that I'm aware of came from ML, and one of the main guys in the ML community back then stressed that "tactic" combinators were only possible when you had a type system for higher-order functions. Often, when I'm working with monads and monad transformers, I'm not really thinking about code or thinking about what a function does. It's too abstract for me by that point. I get by just thinking entirely at the level of types. And I really don't want my frequent mistakes to show up as runtime exceptions. Given the heavy dosage of lambdas involved, I expect most of those exceptions to be thrown from closures a good distance away from the original error.

I see, your work is pretty interesting :)
mizvekov
 
Posts: 314
Age: 37
Male

Brazil (br)
Print view this post

Re: Programming

#14  Postby stalidon » Mar 09, 2012 12:31 pm

What do you guys work at/study? I never completed uni, but I've been a programmer since the 80's ;)

I have a small IT company and been in the 'industry' for a long time. Let me tell you: if you want to keep working with interesting stuff like this, stay as far away as you can from the 'industry'.
-
stalidon
 
Posts: 145
Age: 47
Male

Country: Argentina
Argentina (ar)
Print view this post

Re: Truth is relative: why do we criticize religion?

#15  Postby VazScep » Mar 09, 2012 9:12 pm

mizvekov wrote:Yes, there are a few additions to the standard, that came from boost, that will help here.
You can start by using std::shared_ptr, which is a reference counted pointer container, that will delete automatically when the count reaches 0.
Code: Select all
struct B {
        int val;
        B(int v) : val(v) {}
        ~B() { std::cout << "bye " << val << std::endl; }
};

std::function<int(int)> f(std::shared_ptr<B> b) {
        return [b](int a) -> int { return a + b->val; };
}

std::function<int(int)> g() {
        auto a = std::make_shared<B>(10), b = std::make_shared<B>(20);
        return f(a);
}
int main() {
        {
                auto foo = g();
                auto bar = std::bind(foo, 1);
                std::cout << foo(2) << ' ' << bar() << std::endl;
        }
        std::cout << "the end" << std::endl;
}

This will print
Code: Select all
bye 20
12 11
bye 10
the end

I am also using std::function there too, which is a polymorphic wrapper for any callable type.
:awesome: That's seriously cool.

I guess my sniveling concern is adoption. Having first-class lambdas could open up C++ to a lot of new and enticing solutions to existing problems, before we start getting into the sorts of clever tricks you'll be able to play with classes, subtyping and templates. There could be a lot of libraries that would benefit from having their APIs extended or even rewritten to support the new constructs. I wonder to what extent this will mean that C++ styles and idioms will just become ever more diverse. Isn't this a problem even with vanilla C++, that you still have folk who treat it as C with some extensions?

This is very much a problem which plagues Common Lisp, and I suspect it's one that the Java developers intentionally avoided by keeping their feature set on a tight leash.

Wow, I misjudged the LISP guys, I thought they would find something like that an aberration and kill it with fire.
Nope. Maybe the Schemers would. Those were always the academic sort. But then again, Schemers are obsessed with their call/cc, which is almost as dangerous a construct as GOTO.

Most lisps have always allowed seriously nasty destructive side-effects. I think this is for a number of reasons: firstly, people were building machines that were Lisp all the way down to the hardware, and where the operating system was just a Lisp runtime and the scripting language was the Lisp REPL. The only sort of Lisp that can cope with that is one which can cope extremely well with state and global access to data, and which allows you to happily bring the system crashing down on itself just like you can with a good old UNIX box. This sort of thing also calls for a lot of reflection mechanisms. Just like you can see every program accessible to you at your shell and you can redefine shell commands, you should be able to see every Lisp function in your runtime environment and redefine symbols (and you should be able to look at their source code, and recompile them, and uninline them and relink them --- Common Lisp runtimes still perform many tasks that are normally reserved for the OS, and are typically more sophisticated).

The sort of crazy self-modifying power led to various crazy engineering. Brian Smith had wacky ideas about being able to reflect into what is conceptually your own interpreter, and then reflect again (an arbitrary number of times), redefine your semantics and reflect back down again into a new programming language. This fully working nonsense eventually became the Lisp MetaObject Protocol, a self-bootstrapping OO system that allows you to redefine the behaviour of classes and generic function dispatch in a way which would confuse Lewis Carroll (though the applications of this idea are pretty sweet, such as Allegro Common Lisp's seamless system whereby you can have billions of objects in your runtime which are automatically offloaded into databases when your memory fills up).

Basically, Lisp is a monster, for arguably good reasons. But for some bizarre reason, a lot of universities seem to teach only toy versions of it. I can't remember how many times I've encountered the claim that Lisp is not a compiled language, or the claim that every data structure in Lisp is a cons.

Though I'm a little sceptical about using monads or any combinator language in an untyped language. The first serious combinator languages that I'm aware of came from ML, and one of the main guys in the ML community back then stressed that "tactic" combinators were only possible when you had a type system for higher-order functions. Often, when I'm working with monads and monad transformers, I'm not really thinking about code or thinking about what a function does. It's too abstract for me by that point. I get by just thinking entirely at the level of types. And I really don't want my frequent mistakes to show up as runtime exceptions. Given the heavy dosage of lambdas involved, I expect most of those exceptions to be thrown from closures a good distance away from the original error.

I see, your work is pretty interesting :)
Well, if you're interested at all in formal logic, the original inspiration for ML and its earliest applications (such as Logic of Computable Functions) are still, IMO, some of the smartest and coolest examples of functional programming engineering and awesome uses of type abstraction and higher-order functions. I can throw some simple Haskell code your way if you're interested.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Programming

#16  Postby mizvekov » Mar 10, 2012 3:17 am

stalidon wrote:What do you guys work at/study? I never completed uni, but I've been a programmer since the 80's ;)

Heh, I am not that old, only been doing it since '97 or so :)

stalidon wrote:
I have a small IT company and been in the 'industry' for a long time. Let me tell you: if you want to keep working with interesting stuff like this, stay as far away as you can from the 'industry'.

Duly noted, but the monies are always welcome though ;)
But seriously though, at least if you are working with a small team, there is always room to use something 'interesting', even if you can't go all the way by say, using Haskell, you can always trade a bit of the productivity of using the same tired old stuff for some entertainment, if you can keep the balance right.

VazScep wrote: :awesome: That's seriously cool.

Yes indeed :grin:
shared_ptr has been part of boost for some time now, glad it got accepted.
VazScep wrote:
I guess my sniveling concern is adoption. Having first-class lambdas could open up C++ to a lot of new and enticing solutions to existing problems, before we start getting into the sorts of clever tricks you'll be able to play with classes, subtyping and templates. There could be a lot of libraries that would benefit from having their APIs extended or even rewritten to support the new constructs.

Well, there is a lot of people out there really pumped with all this new stuff, and if you look around, say for instance in github, you will see the place is choke-full of people creating new libs that solve problems already handled by well established ones, except that by doing it the c++11 way. Some of it is promising, some of it looks like shit, but it's only wait and see now.
About the old libraries, well that varies a lot. There has not been a lot of time since the spec got published, and there is no fully conformant compiler / STL implementation yet. Lot's of libraries in boost for instance have been updated to accept and work well with the new additions, but there are still rough edges and not every new feature has been exploited yet.
But still you have got other libraries like Qt which are still using pretty ancient c++ lingo, and still uses that infamous preprocessor called 'moc', for things that could be done just using the standard lib. I've read on their mailing list that they have committed themselves to supporting at least the new stuff which only requires superficial changes and which can be optional, but I guess they still have to support ancient platforms with no hope of ever seeing a c++11 compliant compiler, so I venture to say that no radical changes in the API are to be expected for years to come. Plus their codebase is pretty huge...

VazScep wrote:
I wonder to what extent this will mean that C++ styles and idioms will just become ever more diverse.

Well yes, right now you will find some cutting edge libs, and also some arcane c++98 ones which don't even use exceptions or the STL containers.
But at least a lot of thought has been put into backwards compatibility, so you could for example use the new fancy stuff and glue it with old interfaces. A lot of the STL containers give you access to the underlying pointer if you ask for it, and so does shared_ptr. I have done this a lot actually.

VazScep wrote:
Isn't this a problem even with vanilla C++, that you still have folk who treat it as C with some extensions?

Well I haven't come across one of those for a long time, but I guess that depends on the area of expertise you are working.
The examples I used to see were of folks doing it just because the visual studio C compiler sucked, so they compiled C code as C++.

VazScep wrote:
This is very much a problem which plagues Common Lisp, and I suspect it's one that the Java developers intentionally avoided by keeping their feature set on a tight leash.

Yes, but the Java guys haven't been always successful at that. Last I checked, their GUI situation was a mess, with AWT, swing, SWT etc still competing. But then looking at that side, the other languages do not fare better, except perhaps C#.

VazScep wrote:Nope. Maybe the Schemers would. Those were always the academic sort. But then again, Schemers are obsessed with their call/cc, which is almost as dangerous a construct as GOTO.

Most lisps have always allowed seriously nasty destructive side-effects. I think this is for a number of reasons: firstly, people were building machines that were Lisp all the way down to the hardware, and where the operating system was just a Lisp runtime and the scripting language was the Lisp REPL. The only sort of Lisp that can cope with that is one which can cope extremely well with state and global access to data, and which allows you to happily bring the system crashing down on itself just like you can with a good old UNIX box. This sort of thing also calls for a lot of reflection mechanisms. Just like you can see every program accessible to you at your shell and you can redefine shell commands, you should be able to see every Lisp function in your runtime environment and redefine symbols (and you should be able to look at their source code, and recompile them, and uninline them and relink them --- Common Lisp runtimes still perform many tasks that are normally reserved for the OS, and are typically more sophisticated).

The sort of crazy self-modifying power led to various crazy engineering. Brian Smith had wacky ideas about being able to reflect into what is conceptually your own interpreter, and then reflect again (an arbitrary number of times), redefine your semantics and reflect back down again into a new programming language. This fully working nonsense eventually became the Lisp MetaObject Protocol, a self-bootstrapping OO system that allows you to redefine the behaviour of classes and generic function dispatch in a way which would confuse Lewis Carroll (though the applications of this idea are pretty sweet, such as Allegro Common Lisp's seamless system whereby you can have billions of objects in your runtime which are automatically offloaded into databases when your memory fills up).

That one is a pretty sweet idea indeed.

VazScep wrote:
Basically, Lisp is a monster, for arguably good reasons. But for some bizarre reason, a lot of universities seem to teach only toy versions of it. I can't remember how many times I've encountered the claim that Lisp is not a compiled language, or the claim that every data structure in Lisp is a cons.

Well, to be 'fair' to them, that was their introductory course to programming, but you would rarely see it again later in the course. I don't think any of the professors had a vested interest in it, I don't remember seeing anything being published on the matter.
Well, if you're interested at all in formal logic, the original inspiration for ML and its earliest applications (such as Logic of Computable Functions) are still, IMO, some of the smartest and coolest examples of functional programming engineering and awesome uses of type abstraction and higher-order functions. I can throw some simple Haskell code your way if you're interested.

Sure I am, thanks :)
mizvekov
 
Posts: 314
Age: 37
Male

Brazil (br)
Print view this post

Re: Programming

#17  Postby mizvekov » Mar 10, 2012 5:26 am

By the way, since we were talking about cool new c++ features, here is another one of my favorites:
Example code of the new random number library, much more powerful and modular:
Code: Select all
// 1.0 is the lambda parameter of the exponential distribution
auto random = std::bind(std::exponential_distribution<double>(1.0), std::default_random_engine());
for (;;)
      std::cout << random() << std::endl;

Will generate numbers like:
Code: Select all
0.330217
3.44907
0.208902
1.28924
0.838482
0.549105
0.0226059

Pretty hard to beat that in elegance :grin:
The modular design means that you can use other generators, like the other pseudo-random ones included in the standard lib, or roll your own, be that another pseudogen, or even one based on reading /dev/random (for unix systems) or which communicates directly with a hardware RNG.
And you can combine any of those with any probability distribution, such as the ones included in the standard (there are several others, like uniform, normal, binomial), or again, create your own.

Pretty neat huh? :grin:
mizvekov
 
Posts: 314
Age: 37
Male

Brazil (br)
Print view this post

Re: Programming

#18  Postby VazScep » Mar 10, 2012 10:47 am

stalidon wrote:What do you guys work at/study? I never completed uni, but I've been a programmer since the 80's ;)
I'm in academia. Figures, eh?

I have a small IT company and been in the 'industry' for a long time. Let me tell you: if you want to keep working with interesting stuff like this, stay as far away as you can from the 'industry'.
I'm considering industry at some point. There are jobs out there where they're using this stuff. I have friends who code in ML for their day-job, and many of the general ideas are leaking through into mainstream languages. C# is totally mainstream, and is a pretty damn interesting language, precisely because of the amount of influence it's had from functional programmers working at Microsoft Research.

Still, I think I could have fun just doing this stuff in my spare time. The perl-mongers here in Edinburgh, and half the people who attend our functional programming meetup are in industry, and they're all interested in this sort of stuff.
Here we go again. First, we discover recursion.
VazScep
THREAD STARTER
 
Posts: 4590

United Kingdom (uk)
Print view this post

Re: Programming

#19  Postby stalidon » Mar 10, 2012 10:54 am

mizvekov wrote:
But seriously though, at least if you are working with a small team, there is always room to use something 'interesting', even if you can't go all the way by say, using Haskell, you can always trade a bit of the productivity of using the same tired old stuff for some entertainment, if you can keep the balance right.


Oh yeah, I'm all for entertainment. Wouldn't dream of having a dev team without it. ;)

In the general 'industry' however... they want you to produce 'readable' code. That is, code that can be read by an 'analyst' that specializes in Excel macros. :naughty2:

Teu nick parece russo ;)

:cheers:
-
stalidon
 
Posts: 145
Age: 47
Male

Country: Argentina
Argentina (ar)
Print view this post

Re: Programming

#20  Postby advaitya » Mar 10, 2012 11:03 am

I fail to see the philosophy in this thread? Ought to be shoved in some other appropriate forum.
advaitya
 
Posts: 323
Age: 39
Male

Country: India
India (in)
Print view this post

Next

Return to Philosophy

Who is online

Users viewing this topic: No registered users and 1 guest