Share

Kokogut - a compiler of Kogut

File Release Notes and Changelog

Release Name: 0.6.0

Notes:
Please download kokogut-0.6.0-boot.tar.bz2 unless you already
have Kokogut installed in version 0.5.0 or later.

Changes: A release with imperative iterators and number formatting: - Changed the default iteration protocol and the nature of generators. There were two major problems with old iterators: the primary iteration function, Traverse, executed the same action for each element, and thus too often clients needed to use a different and less efficient mechanism (Next); and while the interface of generators didn't rely on mutable state, some generators worked correctly only when used linearly. Now the function Iterate starts iteration and returns a stateful iterator. When an iterator is applied to two arguments, by convention called 'absent' and 'present', it checks whether there are more elements; if yes, it cuts the next element and enters 'present elem', otherwise it enters 'absent()'. It may be called again after the end. The function Iterate can be applied to any number of collections. In general it returns a multi-iterator which applies 'present' to the appropriate number of elements, until any collection ends. A generator is a "virtual" collection designed to be iterated over. It's created by 'Generate {code}', where the code makes a new iterator; when the generator is applied to no arguments or when Iterate is applied to it, it executes the code. Most generators may be iterated over multiple times, but some of them (e.g. those reading from files) may not. - New: * GetFirst, TryCutFirst * MapPartial, MapPartialGen - like Map and MapGen, but you may Pass() instead of providing an element * ReverseList, MapReverseList - reversing with the output going to a list, more efficient than Reverse{,Gen} with conversion * MapSepBy, MapEndBy * Average, MapAverage * MinimumBy, MaximumBy * EmptyIterator, EmptyGenerator * NextPermutation - takes a list and an optional less-than predicate, returns the lexicographically next permutation or Null if it was already the last one * ReadBytes{,Gen,Lazy}From * ReadChars{,From} - now returns an array * ReadLines{,From} - now returns a list * SkipLine{,From} * AnyCharExcept in module Parsec * DirectoryContents - now returns a list * {,Neg}InfFloat, NaNFloat, IsInfinite, IsNaN, SignBit * Hypot in module Math * SizeInBits * {Min,Max}SmallInt, IsSmallInt, Unsafe{Eq,NE,Quot,Rem,Div,Mod, IsDivisible,IsEven,ShiftL,ShiftR,SizeVector,AtVector} in module Unsafe - Renamed: * Rest -> RemoveFirst * Some -> Any * ListSort{,By} -> SortList{,By} * NextMany -> MapNext * Iterator -> ViewSequence * Generate -> Collect (new) * Gen{Map,Join,MapJoin,MapPairs,Select,Reject,Unique,UniqueBy} -> {Map,Join,MapJoin,MapPairs,Select,Reject,Unique,UniqueBy}Gen * Read{Chars,Lines}{,From} (old) -> Read{Chars,Lines}Lazy{,From} * GenRead{Chars,Lines}{,From} -> Read{Chars,Lines}Gen{,From} * DirectoryContents (old) -> DirectoryContentsLazy * GenDirectoryContents -> DirectoryContentsGen * ProgramOutputLines (old) -> ProgramOutputLinesLazy * GenProgramOutputLines -> ProgramOutputLinesGen * COLLECTION_EMPTY, CollectionEmpty -> EMPTY_COLLECTION, EmptyCollection * TimeAfter -> AbsoluteTime - Removed: * Unfold, Iterate (old), IterateIncl, Collect (old), GenCollect * using macro; use Using and Using_ functions instead * IsOdd; use ~IsEven instead * IsNegZero; compare with 0 and use SignBit instead - Function String no longer converts elements of sequences with String again. It used to be inconsistent, depending on the sequence type. - {Select,Reject}{,Gen} may be applied to more than one collection. Returned elements come from the first collection. - Removed SetWhenAbsent. Added SetDefault instead, which applies the given function to no arguments instead of to the key. This was the most common usage. - Function Sqr moved from module Math to Prelude. - Options for Show for numbers (the implementation is based on the paper "Printing Floating-Point Numbers Quickly and Accurately" by Robert G. Burger and R. Kent Dybvig): * base:b, default 10 - number base, between 2 and 36. This option does not apply to the exponent which is always shown in decimal if present at all. No base marker is added automatically, it can be injected through the sign option if wanted. * mixed:False|True, default True - when showing a vulgar fraction with the absolute value greater than 1, whether to show the integral part separately instead of writing an improper fraction. * scientific:False|True|(min, max), default (-4, 15) for floats and (-4, Inf) for ints and ratios - whether to use the scientific format. If it's a pair and fixedDigits is not Null, it's treated the same as False. Otherwise a pair determines the range of exponents (corresponding to the range between b^min and b^max of the absolute value of numbers) outside which the scientific format it always used. Sufficiently large numbers inside the range still use the scientific format if not all their integral digits would be precise. Scientific format is never used with vulgar fractions. * fixedDigits:n|Null, default Null - number of digits shown after the point, either for the regular format (absolute precision) or for the scientific format (relative precision). Trailing zeros are added as needed. Null means to show as few digits as possible for maintaining full precision. * digits:n, default 1 - minimal number of digits shown before the point. Leading zeros are added as needed. This option does not apply to the scientific format. If digits == 0, the number 0 can show no digits at all, unless other options imply otherwise. * inexact:Null|0|1, default Null - if not Null, inexact numbers always show the point and the given minimal number of digits after the point. This allows to distinguish integers, ratios and floats based on their printed representations. * precision:n|Null, default Null - number of digits assumed to be accurate (relative precision). Null means to assume the inherent precision of the type. This option also limits the maximal number of significant digits shown, unless overridden by fixedDigits. * fracPrecision:n|Null, default Null - like precision, but expressed in digits after the point (absolute precision). * sign:(pos, neg), default ("", "-") - sign markers. * imagSign:(add, sub, pos, neg), default ("+", "-", "", "-") - sign markers for the imaginary part. First two are used when the real part is shown, last two when not. * imag:(timesI, i), default ("*I", "I") - suffix is added after the imaginary part, except when it's 1 or -1, in which case unit is used. * special:(inf, nan), default ("Inf", "NaN") - how to show infinity and not-a-number. * mixedSign:(pos, neg), default ("+", "-") - written between the integral and fractional part, if the mixed fraction format is used. * slash:str, default "/" - written between numerator and denominator if the vulgar fraction format is used. * case:#upper|#lower, default #upper - the case of letters used as digits above 9. * point:str, default "." - how to show the point. * insignificant:ch, default "0" - how to show trailing insignificant digits. They might have to be shown if fixedDigits is big enough, or if a large number is shown with scientific forced to False. Scheme uses "#" for this purpose. * exp:str, default "e" - the exponent marker. * expSign:(pos, neg), default ("+", "-") - sign option for the exponent. * expDigits:n, default 2 - digits option for the exponent. Ratios are shown as vulgar fractions when fixedDigits, precision and fracPrecision are all Null, even if the scientific option would imply the scientific format, because it would be unclear how many digits to show. For complex numbers the imaginary part is not shown if it's equal to 0; the real part is not shown if it's equal to 0 and the imaginary part is shown; the absolute value of the imaginary part is shown as a mere imaginary unit instead of a number multiplied by the imaginary unit if the number is equal to 1. If inexact is Null, equality here permits also floats, except negative zero. - Changed rules of weak references. Previously a key of a weak reference was considered dead if it was reachable only through finalizers. This meant that one could safely reference a key from its own finalizer, but finalizers could not rely on other objects being usable when they are run. Now the key keeps just the value alive, and finalizers are considered strongly reachable until they are run, together with everything they need. The finalizer may not refer to the key, or the key will never be finalized. You can use finalizers to constrain the order of finalization. A consequence for usage is that an object might have to be split into two parts: an outer part which has a weak reference attached and refers to the inner part, and an inner part which is referenced from the finalizer. - In synchronous mode signals are only handled while waiting for a thread, I/O, a timeout, or while sleeping forever; and only when actually waiting. They are not handled while waiting for a mutex, a read-write lock, a lazy variable, a weak reference finalizer; or when the reason to wake up is true immediately. Lazy variables no longer support CommitLazy with bouncing between obtaining a resource (in synchronous mode) and computing the value (with signals blocked). Lazy lists however support the old semantics of lazy variables with respect to signals, and support CommitLazy. Thus the obtaining phase can wait for another lazy list while being interruptible. - Event queues: a mechanism for serializing multiple sources of events. An event is in general handled in two phases: one function waits until it is ready, and another one confirms that you want to handle it now. Confirming some events has side effects (e.g. reading a line from a text stream removes it from the stream) and thus it might be important to confirm only one event at a time. 'EventQueue()' makes a new event queue, of type EVENT_QUEUE. 'RegisterEvent queue can do' adds to the queue a new source of an event, where 'can' is a nullary function which waits until the event is ready, and 'do' is a nullary function which confirms the event. 'TakeEvent queue' waits until one of the events happens, and returns the result of the 'do' function of the first event which was ready. A given event is handled at most once. The 'do' function is applied with signals in synchronous mode, and with one signal pending, of type NOT_YET. If it would have to wait for the event, this means that the event is no longer ready, or that it was only partially ready and we must wait for more data. In this case the 'do' function will handle the signal and fail, and TakeEvent will continue waiting. This implies that 'do' should behave sensibly if restarted after being interrupted synchronously. If the event needs no confirmation, the 'do' function might not do anything but return a value; 'do' will only be applied after 'can' returns. The 'do' function usually tags the result so it can be distinguished from other events. Examples of functions to be used in 'can' which are suitable for various functions used in 'do' (they are new): * CanReadFrom for ReadBlock, ReadByteFrom, ReadChar{,From} * CanReadLineFrom for ReadLine{,From} * CanWriteTo for WriteBlock, Flush{,To}; WithInfiniteBuffer can be used before to fill the buffer with data for flushing * CanPut for Put * CanTake for Take * CanTakeFirst for TakeFirst * CanTakeEvent for TakeEvent * CanConnect for Connect in module Network.Sockets; BeginConnect can be used before to initiate asynchronous Connect * CanAccept for Accept in module Network.Sockets; BeginAccept can be used before to initiate asynchronous Accept * CanReceive for Receive{,From} in module Network.Sockets * CanSend for Send{,To} in module Network.Sockets * CanReadFrom RawStdIn for GetCh in module TextUI.Curses Examples of events which need no confirmation: Sleep, Wait (if we know that the condition won't become false again), WaitForThread. Examples of events where waiting for them to be ready without confirming them is unimplementable, so they are always confirmed when waiting finishes even if they are not handled immediately: Open{Raw,Text,Binary}File, WaitForProcess. - Registering a value in a registered list is done with the Register function, instead of applying the registered list itself. Registered lists are sequences: they are operated on using Iterate, TryCutFirst and other generic sequence functions. Iteration over a registered list now takes a snapshot of its state from the beginning of the iteration; this round is not affected by changes of the state after the iteration has started. - If the body of a 'try' case is prefixed with 'handled:', the exception is considered handled when the body is executed. This means that the stack is unwound and the signal blocking state is restored. - If an object we extend or a feature we include is prefixed with a label, the base object is available under this label instead of 'base'. - New syntax of a definition: 'ref name = expr' is equivalent to 'let (ref name) = expr'. New syntax of a pattern: 'set variable' is equivalent to 'private tmp & define {variable = tmp}'. - 'case e ?x => ...' is equivalent to 'case e [x {...}]'. - In character output buffers flushLines is #none by default, except for StdOut, StdErr, and sockets, where it's #soft as before. - DefaultBufferSize is a dynamic variable instead of a constant, used by CopyStream. - Swapped arguments of ShowParensIf. - New functions ShowException and ShowSourceLoc instead of specializing the generic Show. By default Show should format the value in a way which is suitable as a subexpression of another value. - DecodeFloat returns the mantissa normalized, such that changing it by 1 yields the smallest increment of the original value. - New test: Hamming. - Unicode character database updated to Unicode 4.1.0. - Programs which use a deep stack don't use so much time in GC because minor GC now scans only the changed part of the stack. - Detection of pthreads should be more portable. - Bugs fixed: * Functions operating on flat sequences where the sequence size is a valid index (e.g. AddPart or IsGraphemeClusterBoundary) did not accept that index in Kokogut-0.5.3. * IsWordBoundary was True before control characters, should be False. * Python sys.argv is set to Kogut Parameters. Not sure whether this was a bug but pygtk crashed when there was no sys.argv.