Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-08 Thread Paul R
Joachim point taken, if you are already building on a transformer
Joachim stack, adding yet another layer is not a problem. I’m having
Joachim mainly pure code in mind.

I think we need an other word than pure here. Usually, we understand
pure as always producing the same result when given the same
parameters. Here, always really means always, and does not depend
on the run-time context of the program. So obviously, a really pure
function can't use side-effect run-time constants.

IIUC, what you want is run-time qualified functions, or functions that
In the scope of a run, always produce the same result when given the
same parameters. Is that right ?

-- 
  Paul

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-08 Thread Joachim Breitner
Hi,

Am Donnerstag, den 08.09.2011, 09:21 +0200 schrieb Paul R:
 Joachim point taken, if you are already building on a transformer
 Joachim stack, adding yet another layer is not a problem. I’m having
 Joachim mainly pure code in mind.
 
 I think we need an other word than pure here. Usually, we understand
 pure as always producing the same result when given the same
 parameters. Here, always really means always, and does not depend
 on the run-time context of the program. So obviously, a really pure
 function can't use side-effect run-time constants.
 
 IIUC, what you want is run-time qualified functions, or functions that
 In the scope of a run, always produce the same result when given the
 same parameters. Is that right ?

yes, although I understand “pure” as that, e.g. always within one run of
the program. This is in line with some other “constants” as those in in
GHC.Constants and System.Info in base.

What breaks if we allow functions to be pure only within one run of the
program?

Greetings,
Joachim



-- 
Joachim nomeata Breitner
  m...@joachim-breitner.de  |  nome...@debian.org  |  GPG: 0x4743206C
  xmpp: nome...@joachim-breitner.de | http://www.joachim-breitner.de/



signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-06 Thread Joachim Breitner
Hi,

Am Dienstag, den 06.09.2011, 08:15 +1000 schrieb Erik de Castro Lopo:
 Joachim Breitner wrote:
 
  The big downside is the verbosity of the approach: A lot of parameters
  need to be passed, and if one such value is suddenly required in a
  function where it was not before, this function’s signature and all
  functions using it have to be modified. Also, I expect that the explicit
  passing causes a small performance penalty.
 
 Can't this be mostly solved by putting all these configuration parameters
 in a struct and then using implicit parameters:
 
 
 http://www.haskell.org/ghc/docs/latest/html/users_guide/other-type-extensions.html#implicit-parameters
 
 The nice thig about this approach is that is not a single unsafe operation
 needed.

that would work sufficiently if we had support partial type signatures,
e.g. could specify the types of functions “up to” implicit parameters.
Then, using a parameter somewhere where it was not used before does not
require propagating code changes.

Also, implicit parameters have the feature that they can be changed
locally.

Note that using unsafe operations is not a problem if the compiler can
verify that they are not unsafe after all, which is what I am hoping
for.

Let me motivate my approach by an analogue. All our existing Haskell
programs would be fine without the type systems, just writing new ones
would be more difficult. This is because the type systems (basically)
only limits the set of valid programs, while enforcing some correctness
condition (here: type safety).

This is analogous to using a regular expression to define some language
of valid words, e.g. well-formed e-mail-addresses. Now assume we want to
add an additional check, e.g. that the address contains one of a list of
keywords, anywhere. We could create a second regular expression of the
form .*(word1|word2|...).* and make sure both regular expressions
match. Alternatively, using our CS education, we know we could construct
a single regular expression that accepts the intersection of the two
languages. But we would not do that, because the expression would become
horribly convoluted.

Back to my proposal, I see a similar pattern here. We have a good type
system to enforce type safety. Now I come along and want to enforce a
different, additional constraint (correct use of run-time constants). I
could try hard to enforce it in the type systems, making it more
complicated and maybe interfering with other uses of it. Or I could add
a second checker that, orthogonal to and maybe using results of the type
checker, enforces this condition.

I’d even go a step further and say that having an accessible, extensible
interface in ghc to add additional checks, that also allows to export
“type” signatures in the module interfaces, would open a door to many
more possible improvements. For example, the recently added notion of
Safe modules falls into this category. Now imagine that you’d not have
to hack on ghc itself but just build a Haskell library and specify some
flag during compilation to add a new property verifying layer to the
language, like bounding rounding errors in floating point calculations,
or even an interface to a full theorem proof checker... but I
digress. :-)


Greetings,
Joachim


-- 
Joachim nomeata Breitner
  m...@joachim-breitner.de  |  nome...@debian.org  |  GPG: 0x4743206C
  xmpp: nome...@joachim-breitner.de | http://www.joachim-breitner.de/



signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-06 Thread Yitzchak Gale
Joachim Breitner wrote:
 ...Usually in Haskell, you’d determine them in the main function and then
 pass them in an argument to all functions needing them, or you wrap that
 in a monad...
 The big downside is the verbosity of the approach: A lot of parameters
 need to be passed, and if one such value is suddenly required in a
 function where it was not before, this function’s signature and all
 functions using it have to be modified.

I'm struggling to understand what problem you are trying to solve.

We're talking about passing a single parameter - a record type,
or a shallow tree, or something else extremely simple.
In the monadic case, we're adding a single Reader component
to the transformer stack.

I'm currently working on a large system, consisting of hundreds
of modules and tens of thousands of lines of code. There
are hundreds of configuration parameters, coming from
configuration files, modules of compiled-in constants,
and the UI. Different subsets of the parameters are needed
in various subsystems.

Doing that in Haskell has been an absolute pleasure, much much
simpler than in any other language I've used for a system
of this size. (I'll spare you the horror of what I had to do once
for a large system written in C++...) I barely have to think about
it - the types reflect the relationships between the configuration
and the various parts of the system, and Haskell's type system
does the rest automatically, guaranteeing correctness. What
else could you ask for?

 Also, I expect that the explicit
 passing causes a small performance penalty.

We're been processing gigabytes of data - doing non-trivial operations
including a kind of image recognition and more - so far with nearly
imperceptible delay. The bottleneck, if there is one, will certainly
not be the configuration subsystem.

I know some Haskell libraries use constructor hiding, or even
the data-default package which uses generics, to add more
flexibility to the configuration system. But I don't feel the
need even for those. I certainly wouldn't dream of dragging in
type-level olegery, unsafe coercion, implicit parameters
and other experimental extensions. Simplicity just works.

What case are you thinking about? A system several orders
of magnitude more complex? Some special case that creates
difficulty?

Thanks,
Yitz

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-06 Thread Jon Fairbairn
Joachim Breitner m...@joachim-breitner.de writes:

 Hi Cafe,

 this is an idea that has been floating in my head for a while, and I’m
 wondering about its feasibility and, if feasible, complexity (in the
 range from „trivial“ over “blog post” over “paper” to “thesis”).

 Application authors in Haskell often face the problem of run-time
 constants, e.g. values that are expected to be determined once during
 program start and then stay fixed for the remainder of the run. Good
 examples are user configuration values (--verbose, certain paths,
 debugging level, etc.).

There are two aspects to this, both of which have potential
solutions that I’ve been thinking about on and off for a long
time.

The first is command line arguments.

As far as I’m concerned they ought to be passed as a parameter
to the whole programme. So instead of main being a value
exported to the outside world and all importing of values being
done through the IO monad, we would have main going out and
argv::[String] as a global variable (which, of course would not
change during any run of the programme). The alternative version
of this, to make main::[String] - IO ExitCode has a superficial
cleanliness but doesn’t help with the general problem of having
to pass these things about, and in fact makes no real difference
to the referential transparancy of a programme.

The second is configuration data in files.

This seems to fall into two parts: the data that can be fixed at
link time and the data that changes from run to run. For the
former, a simple solution would be to have a facility to compile
a module from non-haskell data. This can be done with template
Haskell doing IO. So that leaves configuration data that changes
from run to run.

-- 
Jón Fairbairn jon.fairba...@cl.cam.ac.uk
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2010-09-14)


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-06 Thread Joachim Breitner
Hi Jon,

Am Dienstag, den 06.09.2011, 14:01 +0100 schrieb Jon Fairbairn:
 Joachim Breitner m...@joachim-breitner.de writes:
  this is an idea that has been floating in my head for a while, and I’m
  wondering about its feasibility and, if feasible, complexity (in the
  range from „trivial“ over “blog post” over “paper” to “thesis”).
 
  Application authors in Haskell often face the problem of run-time
  constants, e.g. values that are expected to be determined once during
  program start and then stay fixed for the remainder of the run. Good
  examples are user configuration values (--verbose, certain paths,
  debugging level, etc.).
 
 There are two aspects to this, both of which have potential
 solutions that I’ve been thinking about on and off for a long
 time.
 
 The first is command line arguments.
 
 As far as I’m concerned they ought to be passed as a parameter
 to the whole programme. So instead of main being a value
 exported to the outside world and all importing of values being
 done through the IO monad, we would have main going out and
 argv::[String] as a global variable (which, of course would not
 change during any run of the programme).

Right. You already think of the command line parameters as constants and
expect them to be provided to you as such. My idea enables that, but not
only for command line parameters but anything that you know is
initialized at the start of the program.


Greetings,
Joachim

-- 
Joachim Breitner
  e-Mail: m...@joachim-breitner.de
  Homepage: http://www.joachim-breitner.de
  Jabber-ID: nome...@joachim-breitner.de


signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-06 Thread Joachim Breitner
Hello,

Am Dienstag, den 06.09.2011, 15:17 +0300 schrieb Yitzchak Gale:
 We're talking about passing a single parameter - a record type,
 or a shallow tree, or something else extremely simple.
 In the monadic case, we're adding a single Reader component
 to the transformer stack.

point taken, if you are already building on a transformer stack, adding
yet another layer is not a problem. I’m having mainly pure code in mind.

  Also, I expect that the explicit
  passing causes a small performance penalty.
 
 We're been processing gigabytes of data - doing non-trivial operations
 including a kind of image recognition and more - so far with nearly
 imperceptible delay. The bottleneck, if there is one, will certainly
 not be the configuration subsystem.

Hmm, maybe I am underestimating ghc, but I’d expect that while it could
create very good code for some tight recursion loop in the IO monad, I’m
not so confident that it could do that for a recursion in (ReaderT IO)
or an even more complex monad stack.

But you are right, other than this special case, the performance issues
are surely not in setting parameters.

 What case are you thinking about? A system several orders
 of magnitude more complex? Some special case that creates
 difficulty?

I think the benefit you get from being able to treat runtime constants
as plain values manifests mostly when writing pure code. If your code
has already been written or re-written in monadic style, adding a
transformation layer is indeed less of a problem.

Greetings,
Joachim

-- 
Joachim Breitner
  e-Mail: m...@joachim-breitner.de
  Homepage: http://www.joachim-breitner.de
  Jabber-ID: nome...@joachim-breitner.de


signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-06 Thread Stephen Tetley
On 6 September 2011 15:33, Joachim Breitner m...@joachim-breitner.de wrote:


 I think the benefit you get from being able to treat runtime constants
 as plain values manifests mostly when writing pure code. If your code
 has already been written or re-written in monadic style, adding a
 transformation layer is indeed less of a problem.

Run time constants are still an effect, though, just like error,
state, IO... that's why they are usually propagated with the Reader
monad or sometimes implicit params.

This does seem to irritate newcomers on Stack Overflow who don't
equate constant (but not statically known) values with more active
effects like state or file IO.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-05 Thread Joachim Breitner
Hi Cafe,

this is an idea that has been floating in my head for a while, and I’m
wondering about its feasibility and, if feasible, complexity (in the
range from „trivial“ over “blog post” over “paper” to “thesis”).

Application authors in Haskell often face the problem of run-time
constants, e.g. values that are expected to be determined once during
program start and then stay fixed for the remainder of the run. Good
examples are user configuration values (--verbose, certain paths,
debugging level, etc.).

Usually in Haskell, you’d determine them in the main function and then
pass them in an argument to all functions needing them, or you wrap that
in a monad. This works and has the advantage of being explicit. One can
locally change the value when passing it to another function – this can
be a good thing (more powerful) or a bad thing (if the programmer had
runtime-constant behavior in mind, an invariant not enforced by the type
system or the compiler).

The big downside is the verbosity of the approach: A lot of parameters
need to be passed, and if one such value is suddenly required in a
function where it was not before, this function’s signature and all
functions using it have to be modified. Also, I expect that the explicit
passing causes a small performance penalty.

A less idiomatic approach would be something like this:

==
module M
confRef = unsafePerformIO $ newIORef (error not set yet)
conf = unsafePerformIO $ readIORef confRef
f = ... conf ...
==
import M
main = do
  ...
  writeIORef confRef theValue
  ... f ...
==

This has the nice effect that the programmer can use conf as if it is
a proper constant value. It could also be quicker, as nothing needs to
be passed on the stack. But besides the subtle issues about inlining,
this has the big issue of glaring unsafeness: There is no guarantee that
confRef is actually set before conf is evaluated, and any code can
easily change the confRef anywhere during the runtime.


I’d like to propose (on the theoretical level for now, don’t worry) an
extension to the language to support _parametrized modules_, which work
internally similar to the example above, but with the compiler
statically ensuring correctness, where correctness means
 * The parameter is not evaluated before it is set.
 * It is set at most once.

Rouch syntax sketch:

==
module M parameters (conf1, conf2)
f = ... conf ...
==
import M
main = do
  ...
  M.setParameters someVal1 someVal2
  ... f ...
==
where setParameters is a symbol generated by the compiler.

The tricky part is, of course, ensuring the correctness. For example
while
 main = do
 M.setParameters 1 2
 ...f...
should be easy to check, how about
 main = do
 id $ M.setParameters 1 2
 ...f...
or even
 main = do
 bool - someIOAction
 guard bool $ M.setParameters 1 2
 ...f...
?

I envision a ghc extensions that would allow to one to hook into the
type checker and attach bits of information (here: „uses conf“ and
„initizalizes M“) to the types, and also check certain conditions (e.g.
a = b is invalid if a and b both have „initializes M“ attached). If
this extension was loaded when id was compiled, it should probably
accept the second case, but when no such information is available, or in
the third case, reject the code. A framework for such attached bits
would surely enable more extensions that statically check some condition
that is hard or unwieldy to express in the type system.

I have more ideas in that direction, but before I start brabbling, maybe
I should first wait for your reactions.

Do you think this could be useful (from a user point of view)? Has this
idea maybe already been proposed? 

Thanks,
Joachim

-- 
Joachim nomeata Breitner
  m...@joachim-breitner.de  |  nome...@debian.org  |  GPG: 0x4743206C
  xmpp: nome...@joachim-breitner.de | http://www.joachim-breitner.de/



signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-05 Thread Gwern Branwen
On Mon, Sep 5, 2011 at 1:43 PM, Joachim Breitner
m...@joachim-breitner.de wrote:
 Do you think this could be useful (from a user point of view)? Has this
 idea maybe already been proposed?

How does it compare with Oleg's typeclass approach?
http://okmij.org/ftp/Haskell/types.html#Prepose

-- 
gwern
http://www.gwern.net

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-05 Thread Joachim Breitner
Hi,

Am Montag, den 05.09.2011, 14:35 -0400 schrieb Gwern Branwen:
 On Mon, Sep 5, 2011 at 1:43 PM, Joachim Breitner
 m...@joachim-breitner.de wrote:
  Do you think this could be useful (from a user point of view)? Has this
  idea maybe already been proposed?
 
 How does it compare with Oleg's typeclass approach?
 http://okmij.org/ftp/Haskell/types.html#Prepose

the big difference is that Oleg’s approach exploits the existing type
system. This is elegant, as it does not need additional support by the
compiler. The “disadvantage”  is that you have to still have to adjust
type signatures (quotes because there is some value in explicitly
stating the use of parameters), and it might (possibly) interfere with
other fancy usages of of the type system.

My proposal adds a second layer of “type” checking, i.e. the terms have
their types as before (and all guarantees by the type system prevail),
and a second round of inference and checking ensures the additional
property of properly setting and using the module¹ parameters.

Another difference is that his system allows for local changes of
parameters, while mine deliberately ensures that a parameter really has
exactly one value during one execution of the program.

Finally, I’d say that my approach is easier to grasp and use by the
programmer.


Greetings,
Joachim


¹ I guess the same approach works even when parameters are not tied to a
specific module, but live on their own. But I guess for clarity of
syntax and use it makes sense to tie them to modules, at least at first.

-- 
Joachim nomeata Breitner
  m...@joachim-breitner.de  |  nome...@debian.org  |  GPG: 0x4743206C
  xmpp: nome...@joachim-breitner.de | http://www.joachim-breitner.de/



signature.asc
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-05 Thread Erik de Castro Lopo
Joachim Breitner wrote:

 The big downside is the verbosity of the approach: A lot of parameters
 need to be passed, and if one such value is suddenly required in a
 function where it was not before, this function’s signature and all
 functions using it have to be modified. Also, I expect that the explicit
 passing causes a small performance penalty.

Can't this be mostly solved by putting all these configuration parameters
in a struct and then using implicit parameters:


http://www.haskell.org/ghc/docs/latest/html/users_guide/other-type-extensions.html#implicit-parameters

The nice thig about this approach is that is not a single unsafe operation
needed.

Erik
-- 
--
Erik de Castro Lopo
http://www.mega-nerd.com/

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Solving the configuration problem with parametrized modules

2011-09-05 Thread David Barbour
On Mon, Sep 5, 2011 at 3:15 PM, Erik de Castro Lopo mle...@mega-nerd.comwrote:

 Can't this be mostly solved by putting all these configuration parameters
 in a struct and then using implicit parameters:


Implicit parameters seem like a fair option. And propagating:

   (?fooConf :: FooConf) = ...

isn't any more difficult than explicit parameters in the type.

I guess the question is whether it is the parameterization or the
*staging *that
seems more relevant.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe