|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
My first real-world Nice experience: impressions and proposalsHi!
I’ve done my first Nice program which performs real-world task. It is a quick and dirty program written for solving one of unexpected problem in my work. The program reads log of SMPP data exchanges from the standard input, searches log records for SMS exchanges, analyzes SMS bodies and detects bad message bodies. I implemented the same task some time ago in D 1.0 (with Tango library) and Eiffel (with EiffelStudio 6.0). So it is interesting to compare solutions on different languages. My Nice implementation could be found here: http://eao197.narod.ru/better_language/test_tasks/decode_7bit_bodies/decode_7bit_bodies.nice.html Here I want to tell about some my impressions and make some proposals for Nice language and its standard library. First of all I want to express my admiration about Daniel Bonniot and others Nice’s contributor’s work – you’ve made very attractive and usable language! Thanks for your efforts! My Nice solution is very similar to D’s one. These languages propose similar set of features for user. D language is more actively developed now and has bigger community than Nice. However Nice is more attractive for me because it offers some features which I miss in D (for example, option types, multi methods) and provides access to large set of Java libraries. So I can say that Nice is more attractive language for every day programming for me than D. However there are some small drawbacks which I’ve met during development. = Drawbacks = == Nice compiler’s error reporting == At first it is error reporting of the Nice compiler. I use VIM editor and run compilation from it. But, unfortunately VIM doesn’t understand format of Nice compiler error messages even with ‘--editor‘ argument. So I think it is good to have yet another format of such messages in the form: <file>:<line>:<column>: <error description> For example: test/main.nice:1:1: undefined symbol X Such format is already supported by several languages/compilers/tools (e.g. C/C++, D, Ruby) and because of that many editors already have support of that format. And Nice compiler shouldn’t tell anything except errors/warning in this mode, i.e. no errors/warnings – no output. == An absence of switch statement == The next is an absence of switch statement in the language. I know that value dispatch mechanism allows write code which illuminates need of switch. But sometimes switch requires much less coding, than using overloaded methods. For example I needed to parse escape sequences in a string. With switch such operation requires simple and obvious switch: if( ‘\\’ == c ) switch( line[ i + 1 ] ) { case ‘r’ : // ‘\r’ processing case ‘t’ : // ‘\t’ processing … case ‘x’: // ‘\xXX’ processing. } But without switch I need to write some top-level overloaded methods for each kind of escape sequence: SomeRetType onChar(current_char, line, index) { … } onChar( ‘r’, line, index) { … } onChar( ‘t’, line, index) { … } … onChar( ‘x’, line, index) { … } … if( ‘\\’ == c ) … = onChar( line[i + 1], line, i+1); or write sequence of if-else-if statements: if( ‘\\’ == c ) { let next = line[i+1]; if( ‘r’ == next ) … else if( ‘t’ == next ) … … } I think that support of value dispatch for local functions could help there, because if allows to write less code then in the case of top-level overloaded methods: if( ‘\\’ == c ) { void onChar( char ch ) { … } onChar( ‘r’ ) { … } onChar( ‘t’ ) { … } … onChar( line[i+1] ); } == Error reporting in getopt library == The next is a error reporting in nice.getopt library. When nice.getopt.parse finds unknown option it prints error messages on the standard error stream and continues argument parsing. But such approach not always desirable. I think it is necessary to have mode in which nice.getopt.parse raises exception on unknown option. == No source file name/line number in the exception stack trace == I use Nice 0.9.13 under Windows and on exception I have that: java.lang.ArrayIndexOutOfBoundsException: 0 at t1.fun.main(Unknown Source) at t1.dispatch.main(Unknown Source) for the program: void main( String[] args ) { try { println( args[ args.length ] ); } catch( Exception x ) { x.printStackTrace(); } } May be it is a bug? = Some proposals = == A kind of Ruby/SmallTalk’s code blocks in Nice == Nice already has syntax sugar for methods with ()->void as last argument: void f( ()-> void action ) { …; action(); … } f() { bla-bla-bla } And may be Nice could support such sugar for other types of lambdas. For example: void g( (A, B, C)-> void action ) { …; action( p1, p2, p2 ); … } g() { |a, b, c| … } where a, b and c will have types A, B and C. It could allow writing less code. For example, I created helper function String formatHelper( PrintStream => void printAction ) { … let ps = new PrintStream( … );… printAction( ps ); … return … } which was used like this: formatHelper( PrintStream printer => { … some actions … } ); Repeating “PrintStream printer =>” on every formatHelper invocation was a boring task. So the form: formatHelper() { |printer| …some actions…} looks more attractive. == Ranges in the form [low,high) == AFAIK, Nice provides Range only in the form [low, high] (each limit included). Because of that sometimes I need to write: for( i : 0..(array.length-1) ) … I think it would be useful if there would be Ranges in the form [low, high) (excluding upper limit). Like in Ruby `…` operator could create such Range: for( i : 0…array.length ) … == Helper method eachLine in the standard library == The standard library contains readLine method. And I know from Ruby that such eachLine could be very useful sometimes: void eachLine ( InputStream from, String->void action ) { let reader = new BufferedReader( new InputStreamReader( from ) ); var line = readLine( reader ); while( line != null ) { action( line ); line = readLine( reader ); } } == Helper method sprintf in the standard library == Sometimes it is necessary to create description of something in the program (for example before raising exception). In that case the following sprintf method could help: String sprintf( String formatString, Object[] args ) { let buffer = new ByteArrayOutputStream(); let printer = new PrintStream( buffer ); printer.printf( formatString, args ); return buffer.toString(); } Example of usage: throw new IllegalValue( sprintf( “value ‘%d’ is out range [%d,%d]”, [ value, low, high ] ) ); -- That’s all now. Thanks for patience. I’ll investigate Nice language further. -- Regards, Yauheni Akhotnikau Senior Programmer Intervale e-mail:eao197@... <mailto:eao197@...> ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Nice-info mailing list Nice-info@... https://lists.sourceforge.net/lists/listinfo/nice-info |
| Free Forum Powered by Nabble | Forum Help |