DocBook tools versionitis?
Last night's build from CVS failed because of the docs: [...] + cd docs + make dvi ps html db2dvi -d /usr/src/packages/BUILD/fptools/docs/fptools-both.dsl installing.sgml tex output file name is jade:/var/lib/sgml/CATALOG.docbk31:24:0:W: DTDDECL catalog entries are not supported jade:OSFD0:1:0:E: end of document in prolog jade:/var/lib/sgml/CATALOG.docbk31:24:0:W: DTDDECL catalog entries are not supported [...] tex file name is dvi file name is This is TeX, Version 3.14159 (Web2C 7.3.1) ** ! End of file on the terminal... why? The `-d' option seems strange: panne@marutea:/usr/src/packages/SOURCES/fptools db2dvi --version db2dvi - docbook-tools 0.5 panne@marutea:/usr/src/packages/SOURCES/fptools db2dvi --help Usage: db2dvi [OPTION]... FILE Run a DocBook SGML document trough various programs. Options: --help display this help and exit -v, --version output version information and exit -x trace the shell script -d, --dvi output DVI -f, --fot output FOT -h, --html output HTML -m, --mif output MIF --pdf output PDF -p, --ps, --postscript output PostScript -r, --rtf output RTF -t, --tex output TeX -j, --jade VAR... set "jade" variables; e.g., "-V %shade-verbatim%" -s, --style FILEuse FILE as driver style HTML: --nochunks don't produce HTML subdocuments; output to stdout Only the last specified output format will be produced. I've tried `-s' instead, but with no success: marutea:/usr/src/packages/BUILD/fptools/docs db2dvi -s /usr/src/packages/BUILD/fptools/docs/fptools-both.dsl installing.sgml tex output file name is installing.tex jade:/var/lib/sgml/CATALOG.docbk31:24:0:W: DTDDECL catalog entries are not supported jade:/var/lib/sgml/CATALOG.docbk31:24:0:W: DTDDECL catalog entries are not supported jade:/usr/src/packages/BUILD/fptools/docs/fptools-both.dsl:1:0:E: character "\" not allowed in prolog jade:/usr/src/packages/BUILD/fptools/docs/fptools-both.dsl:11:0:E: character "{" not allowed in prolog jade:/usr/src/packages/BUILD/fptools/docs/fptools-both.dsl:21:0:E: character "{" not allowed in prolog jade:/usr/src/packages/BUILD/fptools/docs/fptools-both.dsl:21:30:E: end of document in prolog jade:E: specification document does not have the DSSSL architecture as a base architecture jade:E: no style-specification or external-specification with ID "PRINT" tex file name is installing.tex dvi file name is installing.dvi This is TeX, Version 3.14159 (Web2C 7.3.1) (installing.tex JadeTeX 1999/06/29: 2.7 (/usr/share/texmf/tex/latex/psnfss/t1ptm.fd) (/usr/share/texmf/tex/latex/jadetex/isoents.tex) Elements will be labelled ! LaTeX Error: Missing \begin{document}. See the LaTeX manual or LaTeX Companion for explanation. Type H return for immediate help. ... l.8 {2}}B uilding and Installing the Glasgow Functional Programming Tools Suite (/usr/share/texmf/tex/latex/amsfonts/umsa.fd) (/usr/share/texmf/tex/latex/amsfonts/umsb.fd) (/usr/share/texmf/tex/latex/wasysym/uwasy.fd) (/usr/share/texmf/tex/latex/lucidabr/lmrhlcm.fd) (/usr/share/texmf/tex/latex/lucidabr/omlhlcm.fd) (/usr/share/texmf/tex/latex/lucidabr/omshlcy.fd) Overfull \hbox (36.2407pt too wide) in paragraph at lines 8--4647 []\T1/ptm/m/n/10 Building and In-stalling the Glas-gow Func-tional Pro-gram-min g Tools Suite Ver-sion 4.04The GHC Teamglasgow-haskell-$\OMS/cmsy/m/n/10 f$\T1/ ptm/m/n/10 users,bugs$\OMS/cmsy/m/n/10 g$\T1/ptm/m/n/10 @dcs.gla.ac.ukJanuary [1.0.58] [2.0.58] [3.0.58] [4.0.58] [5.0.58] ! I can't find file `installing.aux'. \enddocument ...makeatletter \input \jobname .aux \fi \@dofilelist \ifdim \f... l.4647 ...e{}\endNode{}\endNode{}\endNode{}\endFOT {} Please type another input file name ! Emergency stop. \enddocument ...makeatletter \input \jobname .aux \fi \@dofilelist \ifdim \f... l.4647 ...e{}\endNode{}\endNode{}\endNode{}\endFOT {} Output written on installing.dvi (5 pages, 76420 bytes). Transcript written on installing.log. Suggestions? Cheers, Sven -- Sven PanneTel.: +49/89/2178-2235 LMU, Institut fuer Informatik FAX : +49/89/2178-2211 LFE Programmier- und Modellierungssprachen Oettingenstr. 67 mailto:[EMAIL PROTECTED]D-80538 Muenchen
Re: DocBook tools versionitis?
On Tue, Jan 25, 2000 at 10:33:30 +0100, Sven Panne wrote: Last night's build from CVS failed because of the docs: [...] The `-d' option seems strange: panne@marutea:/usr/src/packages/SOURCES/fptools db2dvi --version db2dvi - docbook-tools 0.5 panne@marutea:/usr/src/packages/SOURCES/fptools db2dvi --help Usage: db2dvi [OPTION]... FILE Run a DocBook SGML document trough various programs. [...] At least debian, (and Redhat IIRC) have different db2xxx tools, it seems... The Debian version of db2dvi (the package name is `cygnus-stylesheets') contains the following lines: [...] # Dave Mason's option to specify a different stylesheet case $1 in -d) DB_STYLESHEET=$2 shift 2 ;; esac [...] IIRC, Sven's version is SuSE home-brewed (and incompatible, of course) ;-)... BTW: I'm, too, not very happy with these db2xxx tools (or jade, the scripts are merely wrappers, IIRC)... the html pages generated from "installation" and "libs" looked better with the old sgmltools. In the current version (with db2html), some links are messed, the generated html files have crappy names... well, this all might go away, once they're truly converted to DocBook, but at least one argument remains: You have to use a stylesheet-capable browser to view the html pages... bye-bye lynx, w3m... :-( Just my $0.02EUR Cheers Michael -- Lehrstuhl-BeleuchtungMichael Weber [EMAIL PROTECTED] Lehrstuhl für Informatik II RWTH Aachen WWW: http://www-i2.informatik.rwth-aachen.de/Software/Haskell/
Re: DocBook tools versionitis?
Michael Weber wrote: [...] IIRC, Sven's version is SuSE home-brewed (and incompatible, of course) [...] I've just realized the same, and immediately sent a bug report to SuSE. :-( Cheers, Sven -- Sven PanneTel.: +49/89/2178-2235 LMU, Institut fuer Informatik FAX : +49/89/2178-2211 LFE Programmier- und Modellierungssprachen Oettingenstr. 67 mailto:[EMAIL PROTECTED]D-80538 Muenchen http://www.informatik.uni-muenchen.de/~Sven.Panne
RE: cannot download ghc-pre-4.06
I wanted to test ghc-pre-4.06 and had made three attempts per week to download http://research.microsoft.com/~simonmar/ghc/snapshot/ ghc-pre-4.06-2117-src.tar.gz FYI, pre-release snapshots are now available as http://research.microsoft.com/~simonmar/ghc/snapshot/ghc-4.06-src.tar.gz via netscape program. After 1-2 hours it gets about 50% of the file and than somewhat breaks, gets out of downloading to the main menu. There is much of the free space on the disk. Earlier, when ghc-4.04 appeared, I downloaded it successfully by the same tool. Being not an expert in this subject, I wonder, which program breaks the downloading. May it be of research.microsoft.com service? I don't know, but I wouldn't be surprised if it were some problem with research.microsoft.com. Has anyone else had any trouble downloading stuff from here? Should I report a bug? Cheers, Simon
Re: cannot download ghc-pre-4.06
Simon Marlow wrote: via netscape program. After 1-2 hours it gets about 50% of the file and than somewhat breaks, gets out of downloading to the main menu. There is much of the free space on the disk. Earlier, when ghc-4.04 appeared, I downloaded it successfully by the same tool. Being not an expert in this subject, I wonder, which program breaks the downloading. May it be of research.microsoft.com service? I don't know, but I wouldn't be surprised if it were some problem with research.microsoft.com. Has anyone else had any trouble downloading stuff from here? Should I report a bug? I had a similar problem downloading the ghc-4.04p1 source code distribution. Since data flows pretty slowly between anywhere in Europe or North America and my machine here in Thailand, I suspected that it was a timeout problem in which the server aborted the transfer after a certain period of time, even if it was not completed (however, that was just a guess). I also happen to be using Netscape (version 4.61). I solved the problem by using the GNU wget program, which can automatically reconnect and continue a transfer that was aborted before it finished. Mark Mark E. Hall Mahanakorn University of Technology Vanit Building 2, 8th Floor 1126/1 New Petchburi Road Bangkok 10400, Thailand 66-2-6553181--7 [EMAIL PROTECTED] http://www.mut.ac.th/~mehall
Re: Haskell Clean
Simon Marlow: Strictly speaking, you can't "evaluate" a value of type (IO a) and have it perform some I/O operations. In fact, there's no way to perform an IO computation in Haskell other than binding it to a value called 'Main.main', compiling and running it. (*) Pablo E. Martinez Lopez: Recall: the type (IO a) is that of PROGRAMS performing I/O, but the EXECUTION of those programs is another matter. And as Simon Marlow pointed out, you have NO means to produce that execution other that binding your IO to Main.main. Well, I see what you mean, no way, NO means, etc. So, the program below in Hugs would not work as it should? Too bad... -- === -- ioio.hs dump f = readFile f = putStr gimmeThat = dump "ioio.hs" -- === Jerzy Karczmarczuk Caen, France
RE: Haskell Clean
Well, I see what you mean, no way, NO means, etc. So, the program below in Hugs would not work as it should? Too bad... -- === -- ioio.hs dump f = readFile f = putStr gimmeThat = dump "ioio.hs" -- === Well, pedantically speaking that's not a program (see Section 5 of the H98 report). Simon
RE: drop take [was: fixing typos in Haskell-98]
| Why not do what python does? Thanks for an interesting suggestion, Alex! However, we are in typo-fixing mode here. In the interests of helping this discussion converge I'm going to exercise my dictatorial powers. Though Alex's suggestion has its attractions, I judge it too big a change to apply at this stage in the H98 process. I think we should adopt one of the three alternatives I proposed. No one has supported C, so we are down to: (A) Make them defined for any n. If n 0, do something reasonable: take: give empty list drop: give whole list (B) Make them defined for n length xs, but fail for n 0. I've heard suppport for both. Personally I favour (A) but only mildly. (B) is a smaller change. Simon
Main reasoning
I permitted myself to protest (veeery mildly) against some very strict statements concerning a non-strict language, of S. Marlow and P.E. Martinez Lopez: In fact, there's no way to perform an IO computation in Haskell other than binding it to a value called 'Main.main', compiling and running it. ... you have NO means to produce that execution other that binding your IO to Main.main. == I have shown an utterly silly script in Hugs, which used readfile f = putStr, and I got from Simon Marlow: Well, pedantically speaking that's not a program (see Section 5 of the H98 report). Simon Oh, thank you. (I will reread the remaining sections as well.) But, if you permit - - with this kind of pedantic reasoning I might have (if I were malicious, which is not the case) said: "There is no way to do ANYTHING even *without* IO, without writing a program containing Main, because it will not execute... (And you don't even need Haskell, this is true in "C" as well). (And I remind you that in your incriminated statement you did not say anything about "Haskell program", but "in Haskell".) But please, let's stop discussing formulations. Jerzy Karczmarczuk Caen, France
Relection
I posted this to comp.lang.functional a while ago but (apparently) no one had an opinion which I cant believe is the case :-) Chris I would be interested to know people's views on adding reflection to Haskell to get Factory-like behaviour. I was thinking that other modules could "export" values as being reflective and the compiled code could register these values at load-time into a list reflections :: [(FullyQualifiedName,Dynamic)] and values could be requested from it a la... lookup :: a - Name - Maybe a Where the initial "a" is needed to make it all typesafe If we had this we could implement additive code i.e. rather than myImageReader :: String - IO Image myImageReader name = case (getExtension name) of BMP - Bmp.readBmp name JMG - Jpg.readJpg name _ - error "unknown type" we could implement myImageReader :: String - IO Image myImageReader name = case (Reflect.lookup (bot::String - IO Image) (makeFnName name) of Just f - f name Nothing - error "unknown type" i.e. passing "myfile.bmp" to makeFnName gives "Bmp.readBmp" and passing "x.yz" to it gives "Yz.readYz" since the list of reflections is built at load time we can extend this functionality by simply linking extra modules with it i.e. main.o can read no file types main.o + bmp.o can read bitmaps main.o + bmp.o + jpg.o can read bmps and jpgs i.e. we do not have to exit case statements and extend types to add extra functionality in Bmp.hs say we could have module Bmp where import Image reflect readBmp readBmp :: String - IO Image ... which would get munged to module Bmp where import Image -- This gets appended to the global reflection list at load time -- [("Bmp.readBmp",toDynamic readBmp)] readBmp :: String - IO Image ... All of this means that the meaning of the code is not the following eval main userAndLibraryDefs but the following eval main (userAndLibraryDefs + LoadTimeDefs) and we still have ref. transparency
RE: Relection
By reflection I mean the sort of thing Java does in java.lang.reflect i.e. given the name/type of a function we can retrieve that function and subsequently use it in the same way that in java given the name of a class we can create instances of that class. i.e. it is quite common to have dialog which accepts a filename looks at the suffix turns that in to class name and picks up the class. That class knows how to deal with files of that type and all classes share a common interface. The sort of problem I'm describing is something I would try to use the Factoy design pattern for nin OO speak (GoF Design Patterns : Elements of Reusable Object-Oriented Software). In Haskell we have module Foo import Bmp ... ... Bmp.read filename i.e. we can only call the functions inside modules we have imported (in this case Foo can read bitmaps because it imports Bmp) However if we wanted to extend Foo's functionality so that it could read Gifs as well we would have to edit Foo module Foo import Bmp import Gif ... ... Bmp.read filename ... Gif.read filename etc and for each new format we wanted to add we would edit Foo.hs ... yeugh! if we had a mechanism for retrieving functions then this would not be necessary we could inspect the filename if it was a .gif then retrieve Gif.read if it was a .bmp then retrieve Bmp.read if it was a .foo then retrieve Foo.read etc now Foo's functionality may be extended in an additive rather than editive way module Foo import Reflect ...let fn = Reflect.getFn (bottom::String - ImageReader) name name = suffix+ ".read" suffix = getSuffix filename in case fn of Nothing - error ("Function that knows how to read " + suffix +" files does not exist") Just f - f filename -Original Message- From: Peter Hancock [mailto:[EMAIL PROTECTED]] Sent: 25 January 2000 11:13 To: Chris Angus Subject: Relection "Chris" == Chris Angus [EMAIL PROTECTED] writes: I posted this to comp.lang.functional a while ago but (apparently) no one had an opinion which I cant believe is the case :-) Hi Chris. The problem is likely to be that (like me) many people don't know what you mean by "reflection" -- I couldn't make it out from your message. [I know what reflection means in set theory, but (pardon my ignorance) I haven't heard of it in FP.] Maybe you could post a URL for a paper which explains this concept well? Regards, Peter
Re: Deprecated features
Sven Panne wrote: Just a thought: Some compilers for other languages (e.g. Java and Eiffel) warn the user about deprecated features, but continue compilation. Given the current state of flux in the Haskell libraries, this would be a nice thing in Haskell, too. So my suggestion is a new pragma DEPRECATED along the following lines: Yes please!
Re: drop take [was: fixing typos in Haskell-98]
Chris Okasaki wrote: For the people that share this sentiment, can you please explain why ints that are too big should not similarly give an error? I can see both being ok, or both being errors. I just don't see why one should be ok and the other an error. IMHO, both should be errors. If we really need, we can provide takeSloppy, takeBackwards, etc, but the default should be a tight as possible to catch errors. I still believe that take and drop should satisfy the compositional laws on legal arguments. Regards, Tommy
Re: drop take [was: fixing typos in Haskell-98]
On Tue, 25 Jan 2000, Chris Okasaki wrote: I'm with the option (B): negatives are just outside the domain of takedrop, and should give you an error message. For the people that share this sentiment, can you please explain why ints that are too big should not similarly give an error? I can see both being ok, or both being errors. I just don't see why one should be ok and the other an error. As a purely _pragmatic_ argument: code that does things by taking blocks of stuff from a list (e.g., some form of block based compression technique) could be written (in broad outline) f [] = [] f a xs =res:f a' zs (ys,zs)=splitAt 40 xs (a',res)=doStuff a xs If the list isn't a multiple of 40 then only doStuff needs to know how to deal with incomplete blocks with B; with values too big being an error f has to check at each point whether there's enough list there before trying the splitAt. So you have a way of ascertaining that length 40 without diverging on infinite lists. It all gets complicated, and this pattern of `eat fixed size chunks while the list isn't depleted' seems common enough to warrant simple programming. I can't think of a pattern of usage that's natural that leads to wanting to take negative portions of the list, but maybe that's my imagination... ___cheers,_dave www.cs.bris.ac.uk/~tweed/pi.htm Farenheit 451 is the temperature at email: [EMAIL PROTECTED] which paper burns. Let's do an experiment to work tel: (0117) 954-5253 see what temperature melts human brain cells.
Re: drop take [was: fixing typos in Haskell-98]
On Tue, 25 Jan 2000, D. Tweed wrote: Oops, fixing two thinko's f _ [] = [] f a xs =res:f a' zs (ys,zs)=splitAt 40 xs (a',res)=doStuff a ys (My haskell coding is getting worse than my C++, which I didn't believe possible...) ___cheers,_dave www.cs.bris.ac.uk/~tweed/pi.htm Farenheit 451 is the temperature at email: [EMAIL PROTECTED] which paper burns. Let's do an experiment to work tel: (0117) 954-5253 see what temperature melts human brain cells.
Re: Reflection (was: Relection)
Chris Angus wrote: | and values could be requested from it a la... | | lookup :: a - Name - Maybe a | | Where the initial "a" is needed to make it all typesafe I don't understand why this extra argument is needed. | Reflect.lookup (bot::String - IO Image) (makeFnName name) If it is just to satisfy the type system, you could equally well leave it out, because the type can be derived from the way the result is used in the program. This is the same problem as in the Dynamic typing extension in Hugs: type Dyn = ... toDyn :: Typeable a = a - Dyn fromDyn :: Typeable a = Dyn - Maybe a (Where "Typeable a" is really there to make sure one does not have a polymorphic use ...) Or the same as a possible eval function: eval :: Result a = String - Maybe a So the type of lookup could just be: lookup :: Reflective a = Name - Maybe a Or maybe a more interesting type would be: lookup :: Name - Dyn I like some of the ideas behind reflection, but I am not sure if I like the exact way you propose this extension. But I don't know enough about reflection to propose something different. Regards, Koen. -- Koen Claessen http://www.cs.chalmers.se/~koen phone:+46-31-772 5424 e-mail:[EMAIL PROTECTED] - Chalmers University of Technology, Gothenburg, Sweden
RE: Relection
Hello everybody, The concept of reflection can also be taken further than Chris' idea, which is fairly useful in it's own right, but could possibly be achieved by some smart FFI-wizard (not sure, this idea just popped into my head). What I'm getting at is some kind of way to get your hands on an abstract syntax representation of a Haskell expression/datatype/module, modifying it, re-typechecking it, and then transforming it back into a Haskell value. This probably would entail carrying Hugs around in the runtime-system and I can imagine you need some kind of monad to protect against unwanted effects. Then you could do things like: module CheckPartition where import HaskellAST import HaskellReflection check :: Reflection String check = do (Binding name body) - getBindingFromString "partition" if body /= haskellParse "\p xs - (filter p xs,filter (not.p) xs)" then return "Read up on the Haskell mailing list!" else return "Way to go!" main = do string - refl2IO check putStr string The possibilities are endless... A fixed(ie standardized) HaskellAST module would be great since every wannabe compiler writer seems to write of her/his own (I know I do!). Maybe that Reflection stuff is slightly unrealistic though... All the best, Jan de Wit
Re: drop take [was: fixing typos in Haskell-98]
Phil Wadler writes: | I'm with Jon Fairbairn on this. Negative arguments are an error | because the domain of take and drop is the naturals. The problem | is that we use Int to represent naturals. -- P | | For the people that share this sentiment, can you please | explain why ints that are too big should not similarly | give an error? I can see both being ok, or both being | errors. I just don't see why one should be ok and the | other an error. I'm with Phil and Jon on this. The "natural" domain for take and friends is the naturals. The question of whether negative arguments are an error or are equivalent to zero may be slightly tricky, though: If we did have the naturals as a type, how would we define the predecessor function on zero? It's either zero or undefined. Negative arguments to take should go the same way. Cheers, --Joe Joseph H. Fasel, Ph.D. email: [EMAIL PROTECTED] Technology Modeling and Analysisphone: +1 505 667 7158 University of Californiafax:+1 505 667 2960 Los Alamos National Laboratory postal: TSA-7 MS F609 Los Alamos, NM 87545
Re: drop take [was: fixing typos in Haskell-98]
I'm with Jon Fairbairn on this. Negative arguments are an error because the domain of take and drop is the naturals. The problem is that we use Int to represent naturals. -- P Yep, this is exactly the same argument we had about this a year or two ago, Phil. My attitude about the "implicit Nat" argument is the same as it was then -- if you want the functions to be over Nat's then *say* Nat in the type, not Int. This could be done in at least two relatively lightweight ways. -- provide a Nat type that maps to unsigned integers -- provide a simple type synonym type Nat = Int along with a prominent comment that any function that *says* Nat in its type should raise an error on a negative argument I would have no arguments with either approach, or with any other approach that makes Nat explicit in the type. But if the type *says* Int, then it should have reasonable behavior for ints. I look at the negative case as being equivalent to standard mathematical treatment of ranges such as i..j, where the range is considered to be empty if j i. Allowing take/drop to handle negative arguments should be useful to exactly the same extent as that mathematical convention. Chris
Re: Relection
Chris Angus wrote: Put simply What do people think about being able to access functions from other modules without importing the module. i.e. Rather than ---Start- import Foo -- call f callFoof x = f x --End We can do ---Start- callFoof x = case (getFunction "Foo.f" (bot::Int - Int) ) of (Just f) - f x (nothing) - error "Foo not linked in" ---End--- My first reaction is "ugh" but on further consideration it is at least an intriguing idea. But I think the syntax is wrong. Perhaps you could have something like this: loadModule :: String - IO Module -- dynamically load module, or raise some -- sort of exception lookupName :: Module - String - IO a -- lookup name or give exception Then code might look like do fooModule - loadModule "Foo" fooF - (lookupName fooModule "f") :: IO (Int - Int) . . . lookupName would need to be a special compiler primitive and there would need to be special compiler magic to pass the most general possible type for its result to the RTS. For example applyFooF x = do fooF - lookupName fooModule "f" return (fooF x) might have to fail except in the unlikely case that Foo.f turned out to have type (for all a,b) ( a - b ).
Re: drop take [was: fixing typos in Haskell-98]
Chris, I admit your argument about symmetry is attractive. If you could put forward a concrete application, on a par with the `break into blocks' application given earlier, you would likely sway me. -- P
Re: Haskell 98: partition; and take,drop,splitAt
As an implementor of eager haskell, I sometimes think it would be nice if all list functions checked the length of their argument, thus stamping out infinite lists forever! In al seriousness, the prelude functions should support a lazy programming style as far as is possible. I found the "split of fixed chunks" idiom very compelling, and would find it difficult to support any semantics that would require length checks before calling take or drop. For a similar reason, I dont think negative arguments to take/drop/splitAt really make sense. I like symmetry arguments---but as a compiler writer I also have another reason to vote for take and drop to work on negative arguments. It allows me to write foldr definitions (which I can deforest, reason about equationally, etc.) without having to scribble down a side condition! -Jan-Willem Maessen
Re: drop take [was: fixing typos in Haskell-98]
Chris Okasaki writes: | But if the type *says* Int, then it should have reasonable behavior | for ints. I look at the negative case as being equivalent to | standard mathematical treatment of ranges such as i..j, where the | range is considered to be empty if j i. Allowing take/drop to | handle negative arguments should be useful to exactly the same | extent as that mathematical convention. I find this persuasive. That suggests these definitions: take _ [] = [] take n _ | n = 0 = [] take (n+1) (x:xs) = x : take n xs drop _ [] = [] drop n xs | n = 0 = xs drop (n+1) (_:xs) = drop n xs splitAt n xs = (take n xs, drop n xs) The call some have made for the tightest possible error checking also has merit, however. That would suggest these definitions: takeExactly 0 _ = [] takeExactly (n+1) (x:xs) = x : takeExactly n xs takeExactly _ _ = undefined dropExactly 0 xs = xs dropExactly (n+1) (_:xs) = dropExactly n xs dropExactly _ _ = undefined splitAtExactly n xs = (takeExactly n xs, dropExactly n xs) I would say that the more loosely-defined functions definitely belong in the library and that it is a matter of taste whether or not to include the tighter ones. Cheers, --Joe Joseph H. Fasel, Ph.D. email: [EMAIL PROTECTED] Technology Modeling and Analysisphone: +1 505 667 7158 University of Californiafax:+1 505 667 2960 Los Alamos National Laboratory postal: TSA-7 MS F609 Los Alamos, NM 87545
Re: fixing typos in Haskell-98
(sorry, can't remember the original author) | The correct definitions would be: | | take -2 -- drops the last 2 elements from the list | (takes everything except the last 2 elements) | drop -2 -- grabs the last 2 elements from the list | (drops everything except the last 2 elements) | | drop n list | n0 = drop (length list + n) list | take n list | n0 = take (length list + n) list | | These are also sane definitions.. Er what happens when I do drop (-1) [] ? Personally I think the whole idea of interpreting negative numbers in a totally different way to non-negative numbers is absolutely barking. For me, "drop (-1)" should produce an error, as it's almost certainly a bug. In any case I think the rule that where everything is defined (drop (x+y)) = (drop x) . (drop y) should be preserved. The other problem is what to do about "take n x" and "drop n x" when length x n. I think there are two solutions: (1) raise an error. This is the easiest solution, and is anyway not so bad, as it is easy to explain and catches a probable bug. But if the user wants more sophisticated behaviour it is easy for them to write a more general version. (2) But if that's not allowed I suggest that the functions return "x" and "[]" respectively.
Re: drop take [was: fixing typos in Haskell-98]
Tue, 25 Jan 2000 12:14:29 -0500 (EST), Chris Okasaki [EMAIL PROTECTED] pisze: I would have no arguments with either approach, or with any other approach that makes Nat explicit in the type. But if the type *says* Int, then it should have reasonable behavior for ints. I can't agree with that argument. What is a difference between "if the type says [a], then it should have reasonable behavior for all lists"? If it's in the definition of reasonable behavior, why tail [] being undefined is reasonable where take (-1) [] is not? It's good when a function is total, but types don't always allow to nicely ensure this. Another similar case: cycle []. AFAIK it used to be [], but now it is undefined. I don't have a strong opinion on either side, although undefined looks a bit more natural: "cycle x = x ++ cycle x" without exceptions. One could easily test for empty argument in constant time anyway. -- __("Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ GCS/M d- s+:-- a22 C+++$ UL++$ P+++ L++$ E- ^^ W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t QRCZAK 5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-
Re: Relection
Tue, 25 Jan 2000 18:12:32 +0100, jwit [EMAIL PROTECTED] pisze: What I'm getting at is some kind of way to get your hands on an abstract syntax representation of a Haskell expression/datatype/module, modifying it, re-typechecking it, and then transforming it back into a Haskell value. In other words you want to embed a Haskell compiler in your program. It could be useful in practice sometimes, but it's a very far concept from a simple extension of the language to allow reflection. Haskell is quite complex and can be compiled. IMHO the distance between the source code and the running program is very big in the case of Haskell. In other words, much is done at compile time instead of runtime. I like this principle, because it allows an elegant and powerful language with lots of static checking and optimizations, even though it makes reflection harder. A function definition is the specification of what an identifier means in its scope, not the physical bytes of its compiled or source code. It can be inlined, instantiated, unfolded, analyzed for strictness, rewritten using RULES etc. - it does not have to appear in a physical form that can be examined by the program. C's dlopen() is different because C is a more low level language - in C there is a closer correspondence between the source function and the execution time object. If you want to embed a compiler or interpreter in your program, then OK, but the compiled or interpreted language need not to have much in common with the language the program is written in. It's cool if it's again Haskell because Haskell is cool (and because it's easier to exchange values) - not because each language should contain a compiler of itself! The compiler used to produce our program and the compiler or interpreter working inside our program are completely different beasts. I would be very careful in designing "reflection capabilities" in Haskell. Especially I'm afraid of producing an inelegant solution which would be abused because of either lack of some other mechamisms or the laziness of a programmer ("laziness" not in FP sense). I agree that we should design a way of allowing dynamic linking of some plugins. IMHO it should be clearly separated from the main language and nicely designed for dynamic linking of additional code, not for examining the program internals by the program itself. Internals that are not relevant for program execution should go away at the time of compilation. Identifiers used in the source should go away. IMHO it should be a sort of FFI specification, allowing linking at runtime. May be Haskell-centric, but formally quite independent of where a program using it came from. Not expressing all the details of Haskell language in first-class values. Not needing to parse Haskell code at runtime to link a module! What I mean by abusing an embedded compiler. For example building function names from pieces and parsing the resulting expression instead of creating a mapping between function names and actual functions. Or translating an arithmetic expression entered by the user to Haskell expression instead of writing a parser of arithmetic expressions. Or passing values between functions by their source name instead of by themselves. Or doing things that are hard to fit in the type system instead of expressing them differently or improving the type system. I don't know what is the GHC and Hugs integration going to look like. I have good feelings about it, only I'm afraid of abusing it or implementing some features along with lack of some more important ones. -- __("Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ GCS/M d- s+:-- a22 C+++$ UL++$ P+++ L++$ E- ^^ W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t QRCZAK 5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-
RE: drop take [was: fixing typos in Haskell-98]
On Wednesday, January 26, 2000 9:12 AM, Joe Fasel [SMTP:[EMAIL PROTECTED]] wrote: The call some have made for the tightest possible error checking also has merit, however. That would suggest these definitions: takeExactly 0 _ = [] takeExactly (n+1) (x:xs) = x : takeExactly n xs takeExactly _ _ = undefined dropExactly 0 xs = xs dropExactly (n+1) (_:xs) = dropExactly n xs dropExactly _ _ = undefined splitAtExactly n xs = (takeExactly n xs, dropExactly n xs) I would say that the more loosely-defined functions definitely belong in the library and that it is a matter of taste whether or not to include the tighter ones. We have seen various proposals about what laws should hold wrt take and drop. I think there is a reasonable presumption that the following very simple laws should hold first: length (take n xs) === n length (drop n xs) === length xs -n This supports Joe's takeExactly/dropExactly definitions. --brian
Re: drop take [was: fixing typos in Haskell-98]
Hi. For H98, I prefer option (A). Option (B) gives an arbitrary dissimilarity with rangeSize and enumFromTo. They currently match the standard mathematical treatment of ranges such as i..j, which Chris Okasaki mentioned. I'm not saying that they're sacred, just that a shift to the style of option (B) is too far-reaching for H98. For any version of Haskell, I prefer that take n x and drop n x (when length x n) should not immediately raise errors, in general. That would be too strict. It's arguable whether errors should be raised in the special case that x == []. How similar should drop 1 be to tail? Regards, Tom
Re: drop take [was: fixing typos in Haskell-98]
Brian Boutel [EMAIL PROTECTED] wrote: We have seen various proposals about what laws should hold wrt take and drop. I think there is a reasonable presumption that the following very simple laws should hold first: length (take n xs) === n length (drop n xs) === length xs -n Does that not imply that "take n xs" when n (length xs) should be an error? I would support that for Haskell 2000, but not for Haskell 98; it's too big a change, and goes far beyond the original goal of resolving the problem of "take n xs | n 0". For Haskell 98, I still favor the proposal: take n xs | n 0 = [] drop n xs | n 0 = xs For Haskell 2000, I feel that the list functions should be consistent in their treatment of empty lists. If "head []" is an error, then "take 2 [1]" should also be an error. And I like having "head []" be an error, because if it returned [], then it seems to me that that would have nasty implications for pattern-matching. I don't want a pattern like "(x:xs)" to match the empty list, which it presumably would if "head []" and "tail []" did not fail (x and xs would both be bound to []). So, if "head []" and "tail []" are going to fail, then other things that imply looking at the head or tail of [] should also fail, including "take 2 [1]" and "drop 2 [1]". Craig
Re: drop take [was: fixing typos in Haskell-98]
Tom Pledger [EMAIL PROTECTED] wrote: Craig Dickson writes: [...] I don't want a pattern like "(x:xs)" to match the empty list, which it presumably would if "head []" and "tail []" did not fail (x and xs would both be bound to []). I don't think it would. Patterns involve data constructors like [] and (:), but not functions like head and tail, which may happen to obey all sorts of rules, but aren't part of the data type definition. True, but I think the standard functions, especially those in the prelude, ought to make sense in terms of the data type's definition, for the sake of presenting a consistent view of that data type to the programmer. If "(x:xs)" does not match [], then the reason for this should be that [] has no head to bind to x, nor tail to bind to xs; and if this is so, then "head []", "tail []", and "take 1 []" should also fail. Conversely, if "head []" and "tail []" succeed, then "(x:xs)" should match the empty list. If this consistency is not maintained, then the language and its core functions are presenting a confusing and somewhat contradictory view of what a list is and how you interact with it. Craig
Re: Relection
On 25-Jan-2000, Marcin 'Qrczak' Kowalczyk [EMAIL PROTECTED] wrote: Tue, 25 Jan 2000 18:12:32 +0100, jwit [EMAIL PROTECTED] pisze: What I'm getting at is some kind of way to get your hands on an abstract syntax representation of a Haskell expression/datatype/module, modifying it, re-typechecking it, and then transforming it back into a Haskell value. In other words you want to embed a Haskell compiler in your program. It could be useful in practice sometimes, but it's a very far concept from a simple extension of the language to allow reflection. Haskell is quite complex and can be compiled. IMHO the distance between the source code and the running program is very big in the case of Haskell. In other words, much is done at compile time instead of runtime. I like this principle, because it allows an elegant and powerful language with lots of static checking and optimizations, even though it makes reflection harder. A function definition is the specification of what an identifier means in its scope, not the physical bytes of its compiled or source code. It can be inlined, instantiated, unfolded, analyzed for strictness, rewritten using RULES etc. - it does not have to appear in a physical form that can be examined by the program. C's dlopen() is different because C is a more low level language - in C there is a closer correspondence between the source function and the execution time object. Well, Mercury has the same approach as Haskell, in the sense of being a language which at least aims at being elegant and powerful with lots of static checking and optimizations. But we do support dynamic linking (on some platforms), using an interface built on top of dlopen() and dlsym(). Supporting dynamic linking need not inhibit optimization to any significant degree, I believe. At worst, you may need to disable inter-module dead-function elimination. Even that need only be done if dynamic linking is used. The next stage of support for reflection, being able to at run-time get your hands on an abstract syntax representation of a Haskell expression/datatype/module, does have a higher cost. The compiler needs to keep information around at run-time which it would otherwise not need. In Mercury we currently support that for types, but not for expressions or modules. One way of reducing the cost of this feature is to require programmers to explicitly mark with some declaration those entities for which the compiler should keep the information around at run-time. ISO Prolog takes this approach; predicates for which you can use the `clause/2' builtin to look up their definition need to be declared "dynamic" using a `:- dynamic' declaration. Ada takes the converse approach: by default, it keeps around some tables to allow you to convert enumeration constants into strings, but there is a standard pragma which allows you to suppress that for a given enumeration. The final stage -- being able to take a representation of a Haskell expression, re-typechecking it, and then transforming it back into a Haskell value -- does not actually _require_ any language or runtime support, I think; you can program it in standard Haskell. Though I guess some support might be required if you want to introduce new types at run-time. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a lethal habit" PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.
Re: drop take [was: fixing typos in Haskell-98]
Chris Okasaki wrote: I'm with the option (B): negatives are just outside the domain of takedrop, and should give you an error message. For the people that share this sentiment, can you please explain why ints that are too big should not similarly give an error? I can see both being ok, or both being errors. I just don't see why one should be ok and the other an error. How about a practical reason: if take has to check the length, it has to scan the whole list to determine whether to return an error. This is more strict (and more complex) than it should be. For example, if we define take like this: take n _ | n0 = error "take: negative argument" take n (x:xs) = x:(take (n-1) xs) take 0 _ = [] take _ [] = error "take: list not long enough" Then the error when n(length l) is buried at the "end" of the list returned by take. OTOH, a drop defined similarly would give an error immediately if n(length l). I don't like that asymmetry, do you? But I definitely don't think negative values make sense for take drop, just as they are an error for (!!). I think we should be able to define (!!) as l !! n = head (drop n l) ...without worrying about what drop will do for negative arguments. A negative index on a list should uniformly be an error. I just consider take to mean "take at most" and drop to mean "drop at most". I like: take 3 (take 50 [1,2,3,4]) == [1,2,3] By the way, replicate is defined in terms of take in the prelude, so what do you think (replicate -1 x) should do? Matt
Re: drop take [was: fixing typos in Haskell-98]
On 25-Jan-2000, Craig Dickson [EMAIL PROTECTED] wrote: Brian Boutel [EMAIL PROTECTED] wrote: We have seen various proposals about what laws should hold wrt take and drop. I think there is a reasonable presumption that the following very simple laws should hold first: length (take n xs) === n length (drop n xs) === length xs -n Does that not imply that "take n xs" when n (length xs) should be an error? I would support that for Haskell 2000, but not for Haskell 98; it's too big a change, and goes far beyond the original goal of resolving the problem of "take n xs | n 0". I agree that it is too big a change for Haskell 98. But I think it would be too big a change for Haskell 2000 too. Making a change like that could cause previously working programs to fail, with no warning at compile time, and with the bug showing up only on certain inputs. The cost of that would far outweigh the benefit (which, in the light of the mixed opinions here, seems dubious anyway). Making non-backwards-compatible changes to the semantics of basic prelude functions like take and drop would be a really bad idea, IMHO. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a lethal habit" PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.
A hard core game programmers view
Take a look at what a hard core game programmer thinks about the evolution of programming languages. Unreal is a very sucessful game so maybe people listen to him... http://www.gamespy.com/articles/devweek_b.shtm You need to read until about page 5 to get to the part I enjoyed most. -- -- Lennart
Re: Relection
This discussion feels like deja-vu all over again! What is wrong with the various generic programming extensions that have already been discussed? Derive, PolyP and their progeny? -Alex- ___ S. Alexander Jacobson Shop.Com 1-212-697-0184 voiceThe Easiest Way To Shop On Wed, 26 Jan 2000, Fergus Henderson wrote: On 25-Jan-2000, Marcin 'Qrczak' Kowalczyk [EMAIL PROTECTED] wrote: Tue, 25 Jan 2000 18:12:32 +0100, jwit [EMAIL PROTECTED] pisze: What I'm getting at is some kind of way to get your hands on an abstract syntax representation of a Haskell expression/datatype/module, modifying it, re-typechecking it, and then transforming it back into a Haskell value. In other words you want to embed a Haskell compiler in your program. It could be useful in practice sometimes, but it's a very far concept from a simple extension of the language to allow reflection. Haskell is quite complex and can be compiled. IMHO the distance between the source code and the running program is very big in the case of Haskell. In other words, much is done at compile time instead of runtime. I like this principle, because it allows an elegant and powerful language with lots of static checking and optimizations, even though it makes reflection harder. A function definition is the specification of what an identifier means in its scope, not the physical bytes of its compiled or source code. It can be inlined, instantiated, unfolded, analyzed for strictness, rewritten using RULES etc. - it does not have to appear in a physical form that can be examined by the program. C's dlopen() is different because C is a more low level language - in C there is a closer correspondence between the source function and the execution time object. Well, Mercury has the same approach as Haskell, in the sense of being a language which at least aims at being elegant and powerful with lots of static checking and optimizations. But we do support dynamic linking (on some platforms), using an interface built on top of dlopen() and dlsym(). Supporting dynamic linking need not inhibit optimization to any significant degree, I believe. At worst, you may need to disable inter-module dead-function elimination. Even that need only be done if dynamic linking is used. The next stage of support for reflection, being able to at run-time get your hands on an abstract syntax representation of a Haskell expression/datatype/module, does have a higher cost. The compiler needs to keep information around at run-time which it would otherwise not need. In Mercury we currently support that for types, but not for expressions or modules. One way of reducing the cost of this feature is to require programmers to explicitly mark with some declaration those entities for which the compiler should keep the information around at run-time. ISO Prolog takes this approach; predicates for which you can use the `clause/2' builtin to look up their definition need to be declared "dynamic" using a `:- dynamic' declaration. Ada takes the converse approach: by default, it keeps around some tables to allow you to convert enumeration constants into strings, but there is a standard pragma which allows you to suppress that for a given enumeration. The final stage -- being able to take a representation of a Haskell expression, re-typechecking it, and then transforming it back into a Haskell value -- does not actually _require_ any language or runtime support, I think; you can program it in standard Haskell. Though I guess some support might be required if you want to introduce new types at run-time. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a lethal habit" PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.
Re: Relection
On 25-Jan-2000, S. Alexander Jacobson [EMAIL PROTECTED] wrote: This discussion feels like deja-vu all over again! What is wrong with the various generic programming extensions that have already been discussed? Derive, PolyP and their progeny? I don't think there's anything fundamentally wrong with them; but I think they only address a small part of the things that reflection (in the wider sense that we've been discussing in this thread) is useful for. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a lethal habit" PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.
Re: drop take [was: fixing typos in Haskell-98]
On 26-Jan-2000, Brian Boutel [EMAIL PROTECTED] wrote: On Wednesday, January 26, 2000 1:52 PM, Fergus Henderson [SMTP:[EMAIL PROTECTED]] wrote: I agree that it is too big a change for Haskell 98. But I think it would be too big a change for Haskell 2000 too. Making a change like that could cause previously working programs to fail, with no warning at compile time, and with the bug showing up only on certain inputs. The cost of that would far outweigh the benefit (which, in the light of the mixed opinions here, seems dubious anyway). Making non-backwards-compatible changes to the semantics of basic prelude functions like take and drop would be a really bad idea, IMHO. Sometimes things are just wrong, and they have to be fixed, however painful that is. I would rather have a definition that makes sense, than one that has always been wrong. This case is not grossly wrong, but it is annoying. Taking and dropping negative numbers of values does not make sense. Sorry, I was probably not making myself clear. In the discussion above, I was talking about making `take n l' and `drop n l' report errors if n length l. That case is probably used quite widely by existing code, and so I think changing it now would be a bad idea. In contrast, I think the `take -1 []' case is the kind of thing that is likely to be used only extremely rarely, if at all, in existing code. I would be happy to change that case to be an error in H98. At the very least we have an inconsistancy in the treatment of negative arguments, which should be fixed. Agreed. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a lethal habit" PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.
Re: Haskell Clean
On Fri, 14 Jan 2000, Arjan van IJzendoorn wrote: So what are the important differences between Clean Haskell? Input and output in Haskell is done through the use of monads. In Clean uniqueness typing is used. Unique (=linear?) types designed for the modelling of the mutable states. Monads also used for this purpose. Q: Exist simple translation of the any monadic program into "unique types style" or not? And the inverse: translation of the program with unique types into monadic style? And the class mechanisms in the two languages are different. However, these differences do not show up in simple cases. So you're right: the languages Haskell and Clean are quite similar. Also Clean have expilcit strictness annotations in the types (and some rules for type inference with strictness annotations). In Haskell we can't does this. Q: May be this is the source of the Clean programs efficiency? Haskell strictness analyzers usually does poor job. Anton