fbpx
× Share your code snippets, screen shots etc. here

Named parameters or How you can simplify your code

  • Wolfgang Riedmann
  • Wolfgang Riedmann's Avatar Topic Author
  • Offline
More
1 year 11 months ago #1 by Wolfgang Riedmann
Named parameters or How you can simplify your code was created by Wolfgang Riedmann
One of the interesting issues in Computer Programming is the possibility to solve problems in more than one way.

Please look at this code (creates a WPF grid with one row and one column):
oGrid := Grid{}	
  oGrid:RowDefinitions:Add( RowDefinition{} )			
  oColDef := ColumnDefinition{}
  oColDef:Width := GridLength{ 10 }
  oGrid:ColumnDefinitions:Add( oColDef )
For every column with a defined width you need at least 3 lines of code!

Possibility 1 - a VO programmer would subclass the ColumnDefinition class:
class MyColumnDefinition inherit ColumnDefinition

constructor()
  super()
  return
  
constructor( oWidth as GridLength )

  super()
  self:Width := oWidth
  
  return
  
constructor( nWidth as int )

  super()
  self:Width := GridLength{ nWidth }
  
  return  
	
end class
and the relative use:
oGrid := Grid{}	
  oGrid:RowDefinitions:Add( RowDefinition{} )			
  oGrid:ColumnDefinitions:Add( MyColumnDefinition{ 10 } )
  oGrid:ColumnDefinitions:Add( MyColumnDefinition{ GridLength{ 10 } } )

Possibility 2 - named parameters, new with X#:
oGrid := Grid{}	
  oGrid:RowDefinitions:Add( RowDefinition{} )			
  oGrid:ColumnDefinitions:Add( ColumnDefinition{}{ Width := GridLength{ 10 } } )

This code is the shortest but looks a bit ugly to me....

And now possibility 3 - with extension methods in the Grid class:
class GridExtensions
	
static method AddRow( self oGrid as Grid, nHeight as double ) as void
  local oRowDefinition as RowDefinition
	
  oRowDefinition := RowDefinition{}
  oRowDefinition:Height	:= GridLength{ nHeight }
  oGrid:RowDefinitions:Add( oRowDefinition )
	
  return

static method AddRow( self oGrid as Grid, oHeight as GridLength ) as void
  local oRowDefinition as RowDefinition
	
  oRowDefinition := RowDefinition{}
  oRowDefinition:Height	:= oHeight
  oGrid:RowDefinitions:Add( oRowDefinition )
	
  return

static method AddColumn( self oGrid as Grid, nWidth as double ) as void
  local oColumnDefinition as ColumnDefinition
	
  oColumnDefinition := ColumnDefinition{}
  oColumnDefinition:Width := GridLength{ nWidth }
  oGrid:ColumnDefinitions:Add( oColumnDefinition )
	
  return

static method AddColumn( self oGrid as Grid, oWidth as GridLength ) as void
  local oColumnDefinition as ColumnDefinition
	
  oColumnDefinition := ColumnDefinition{}
  oColumnDefinition:Width := oWidth
  oGrid:ColumnDefinitions:Add( oColumnDefinition )
	
  return

end class

and now how to use it:
oGrid := Grid{}	 
  oGrid:AddRow( 10 )
  oGrid:AddRow( GridLength{ 1, GridUnitType.Star } )
  oGrid:AddColumn( 10 )
  oGrid:AddColumn( GridLength{ 1, GridUnitType.Pixel } )

You will find a XIDE export file with the full code attached to this message.
Attachments:

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago #2 by Frank Maraite
Replied by Frank Maraite on topic Named parameters or How you can simplify your code
Hi Wolfgang,

in general I like what you say here showing us named parameters and extension methods, but
...

General Guidelines

In general, we recommend that you implement extension methods sparingly and only when you have to. Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type. For more information, see Inheritance.

from
msdn.microsoft.com/en-us/library/bb383977.aspx
...
It is much more flexible creating your own derived Grid class and do the AddRow() method there as a real class member.

Extension methods are a perfect way to extend static classes from .NET namespaces. This way we can implement VO string functions and use them as System.String methods.

Keep up publishing your work.
Thanks
Frank

Please Log in or Create an account to join the conversation.

  • Wolfgang Riedmann
  • Wolfgang Riedmann's Avatar Topic Author
  • Offline
More
1 year 11 months ago - 1 year 11 months ago #3 by Wolfgang Riedmann
Replied by Wolfgang Riedmann on topic Named parameters or How you can simplify your code
Hi Frank,

I fully agree with what you say about extension methods - I added them only to show how different solutions can be.

My favorite, or better the code I use is based on this piece of code (if you look at my XIDE MVVM Enhanced Sample 2 you'll find very similar code):
using System.Windows
using System.Windows.Controls
using System.Windows.Data

class MVVMGrid inherit Grid
	
constructor()
	
  return   
	
constructor( nColumns as int, nRows as int )
	
  super()
  self:Initialize( nColumns, nRows )
	
   return
	
method Initialize( nColumns as int, nRows as int ) as logic
  local nI as int
	
  for nI := 1 upto nColumns
    self:ColumnDefinitions:Add( ColumnDefinition{} )
  next
  for nI := 1 upto nRows
    self:RowDefinitions:Add( RowDefinition{} )
  next
		    
  return true	
	
method SetRowHeightAll( oHeight as GridLength ) as void
	
  foreach oRowDef as RowDefinition in self:RowDefinitions
    oRowDef:Height := oHeight
  next

  return	
	
method SetRowHeight( nRow as int, oHeight as GridLength ) as void
// 0-based	
  if self:RowDefinitions:Count > nRow
    self:RowDefinitions[nRow]:Height := oHeight
  else 
    throw ArgumentOutOfRangeException{ "nRow" }
  endif
	
  return
	
method SetRowHeight( nRow as int, nHeight as int ) as void
// 0-based	
  if self:RowDefinitions:Count > nRow
    self:RowDefinitions[nRow]:Height := GridLength{ nHeight }
  else 
    throw ArgumentOutOfRangeException{ "nRow" }
  endif
	
  return
	
method SetColWidth( nColumn as int, oWidth as GridLength ) as void
// 0-based	
  if self:ColumnDefinitions:Count > nColumn
    self:ColumnDefinitions[nColumn]:Width := oWidth
  else 
    throw ArgumentOutOfRangeException{ "nColumn" }
  endif
	
  return
	
method SetColWidth( nColumn as int, nWidth as int ) as void
// 0-based	
  if self:ColumnDefinitions:Count > nColumn
    self:ColumnDefinitions[nColumn]:Width := GridLength{ nWidth }
  else 
    throw ArgumentOutOfRangeException{ "nColumn" }
  endif
	
  return
	
method AddControl( oControl as UIElement, nColumn as int, nRow as int ) as void
	
  Grid.SetColumn( oControl, nColumn )	
  Grid.SetRow( oControl, nRow )	
  self:Children:Add( oControl )
	
  return
	
end class

This class not only simplifies column and row creation (making code more readable), but also reduces the code to add controls, making it cleaner (in my eyes).

Wolfgang
Last edit: 1 year 11 months ago by Wolfgang Riedmann.

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago #4 by Frank Maraite
Replied by Frank Maraite on topic Named parameters or How you can simplify your code
Hi Wolfgang,

yes, that's fine. The only thing: I would not name it MVVMGrid. Your enhancements have nothing to do with MVVM. Show this in your name. WRGrid is not good too, but better. I name fmGrid, bad too :.( .

Another alternative:
Instead
...
method AddControl( oControl as UIElement, nColumn as int, nRow as int ) as void

Grid.SetColumn( oControl, nColumn )
Grid.SetRow( oControl, nRow )
self:Children:Add( oControl )

return
...
do
...
private method AddControl( Control as UIElement, columnNumber as int, rowNumber as int ) as void

Grid.SetColumn( Control, columnNumber )
Grid.SetRow( Control, rowNumber )
self:Children:Add( Control )

return
public method AddButton( columnNumber as int, rowNumber as int ) as WRButton
local Button as WRButton // or MVVMButto in your naming convention
Button := WRButton{}
AddControl( Button, columnNumber, rowNumber )
return Button
// In the calling method we can do additional things with the button control.
...
The same for all other kinds of controls. It seems overdone, but you will like it.
And for readability: There is no need for 'o' or 'n', but columnNumber says more than nColumn. With this verbose naming it's clear: it cannot be other than a number kind of type. And of course: all types are objects. These 'o's and 'n's are only visual dirt.

Frank

Please Log in or Create an account to join the conversation.

  • Wolfgang Riedmann
  • Wolfgang Riedmann's Avatar Topic Author
  • Offline
More
1 year 11 months ago #5 by Wolfgang Riedmann
Replied by Wolfgang Riedmann on topic Named parameters or How you can simplify your code
Hi Frank,

I call these controls with the MVVM prefix, as they are specifically for MVVM (not the Grid, but the other ones, because of code like this:
public new property Name as string
  get
    return super:Name
  end get
  set
    super:Name := value
    self:SetupBinding()
  end set
end property   

method SetupBinding() as void
  local oBinding as Binding

  oBinding := Binding{ self:Name } 
  oBinding:ValidatesOnDataErrors := true
  oBinding:UpdateSourceTrigger := UpdateSourceTrigger.PropertyChanged
  if ! String.IsNullOrEmpty( _cStringFormat )
    oBinding:StringFormat			:= _cStringFormat
  endif

  self:SetBinding( TextBox.TextProperty, oBinding )
	
  return

This code is from the MVVMTextBox class.

Yes, I could have named it differently....
And yes, I know you would use different method calls and much more private and protected methods, but I prefer the code how I have written it.

And about the prefixes: I prefer to write them as I feel they make the code better to read, and let me distinguish immediatly between the class name and the object iself (important since static methods are applying to the class and not the object):
MyObject.MyStaticMethod()

is clearly differenced from
oMyObject:MyMethod()

And yes, I prefer to have prefixes for the basic types like numerics, strings and logics.

These are all personal preferences, and fortunately everyone can have and maintain these (maybe the thing changes in the same company as I request this programming style in my small company)

Wolfgang

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago - 1 year 11 months ago #6 by Frank Maraite
Replied by Frank Maraite on topic Named parameters or How you can simplify your code
Hi Wolfgang,

I often do

LOCAL myClass AS myClass
myClass := myClass{}

because in many situations the class type name is the best solution for its instance var name. With '.' and ':' different meaning in Vulcan there is no issue with static members and instance members.

A better exampel
CLASS ListOfmyClass inherit System.Collections.Generic.List<myClass>
END CLASS

local ListOfmyClass as ListOfmyClass
ListOfmyClass := ListOfmyClass{}
ListOfmyClass:Add( "123" )
? ListOfmyClass:Count:ToString()
// The code is out of my head now. Should work.

Why rename it? The ListOfmyClass is a ListOfmyClass. It worked in Vulcan and it works in X#.

As I understand X# takes ':' and '.' the same way and calls static or instant member upon there signature. This way I don't have to change my code if a member switches from static to instance for and back. Recompile is needed of course.

I cannot test this new X# behavior now, but will do ASAP.

Frank
Last edit: 1 year 11 months ago by Frank Maraite. Reason: Typo

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago #7 by Karl Faller
Replied by Karl Faller on topic Named parameters or How you can simplify your code
Frank,
pmfji, but i go with Wolfgang - for the simple reason, that "." and ":" are verrry prone to typos as they are to reading faults with tired eyes;)

Frankly, i can't quite get the reason for your crusade against hungarian notation - not everything gets better by using "long" names, as not everything gets bader when shortened to the max without loosing content...

Karl

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago #8 by Frank Maraite
Replied by Frank Maraite on topic Named parameters or How you can simplify your code
Karl,

because it's absolutly senseless. In times of intellisense you move your mouse pointer above your var and see the var type. Comments of a few of the best program theorists (copied from Wikipedia en.wikipedia.org/wiki/Hungarian_notation ):
---
Notable opinions

Robert Cecil Martin (against System Hungarian notation and all other forms of encoding):

... nowadays HN and other forms of type encoding are simply impediments. They make it harder to change the name or type of a variable, function, member or class. They make it harder to read the code. And they create the possibility that the encoding system will mislead the reader.[9]

Linus Torvalds (against Systems Hungarian):

Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged—the compiler knows the types anyway and can check those, and it only confuses the programmer.[10]

Steve McConnell (for Apps Hungarian):

Although the Hungarian naming convention is no longer in widespread use, the basic idea of standardizing on terse, precise abbreviations continues to have value. Standardized prefixes allow you to check types accurately when you're using abstract data types that your compiler can't necessarily check.[11]

Bjarne Stroustrup (against Systems Hungarian for C++):

No I don't recommend 'Hungarian'. I regard 'Hungarian' (embedding an abbreviated version of a type in a variable name) as a technique that can be useful in untyped languages, but is completely unsuitable for a language that supports generic programming and object-oriented programming — both of which emphasize selection of operations based on the type and arguments (known to the language or to the run-time support). In this case, 'building the type of an object into names' simply complicates and minimizes abstraction.[12]

Joel Spolsky (for Apps Hungarian):

If you read Simonyi's paper closely, what he was getting at was the same kind of naming convention as I used in my example above where we decided that us meant unsafe string and s meant safe string. They're both of type string. The compiler won't help you if you assign one to the other and Intellisense [an Intelligent code completion system] won't tell you bupkis. But they are semantically different. They need to be interpreted differently and treated differently and some kind of conversion function will need to be called if you assign one to the other or you will have a runtime bug. If you're lucky. There's still a tremendous amount of value to Apps Hungarian, in that it increases collocation in code, which makes the code easier to read, write, debug and maintain, and, most importantly, it makes wrong code look wrong.... (Systems Hungarian) was a subtle but complete misunderstanding of Simonyi’s intention and practice.[13]

Microsoft's Design Guidelines[14] discourage developers from using Systems Hungarian notation when they choose names for the elements in .NET Class Libraries, although it was common on prior Microsoft development platforms like Visual Basic 6 and earlier. These Design Guidelines are silent on the naming conventions for local variables inside functions.

This says it all

Frank

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago #9 by Frank Maraite
Replied by Frank Maraite on topic Named parameters or How you can simplify your code
Karl,

Karl Faller wrote: Frank,
pmfji, but i go with Wolfgang - for the simple reason, that "." and ":" are verrry prone to typos as they are to reading faults with tired eyes;)

Karl


as I wrote: there (should be) is no difference between '.' and ':'. As long as the method names are verbose and do what the name says it is ok, '.' or ':' gives the same result. For the user of that method it does not make any difference is it static or instance method. And of course: doing the right tests makes you sure your'e right.

Frank

Please Log in or Create an account to join the conversation.

  • Wolfgang Riedmann
  • Wolfgang Riedmann's Avatar Topic Author
  • Offline
More
1 year 11 months ago #10 by Wolfgang Riedmann
Replied by Wolfgang Riedmann on topic Named parameters or How you can simplify your code
Hi Frank,

this is simply a question of personal preferences.

I can follow them was other people says, but I have not to do it.

It is like the use of the INI file: it is long time that Microsoft has discouraged the use, but I use them until today. Microsoft at least 15 years ago recommended to use the registry, and now recommends XML files - but until today I'm very happy with INI files.

Wolfgang

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago #11 by Karl Faller
Replied by Karl Faller on topic Named parameters or How you can simplify your code

Frank Maraite wrote: Karl,

because it's absolutly senseless. In times of intellisense you move your mouse pointer above your var and see the var type. Comments of a few of the best program theorists (copied from Wikipedia en.wikipedia.org/wiki/Hungarian_notation ):...
...This says it all/quote]

Says what? That there are pros and cons.
BTW, your intellisense means you have to point to each damn name to see what it means - thx, that's not the way i read...

Karl
(@Robert: did i do something wrong, or why all of a sudden all paragrafs are centered by default?)

Please Log in or Create an account to join the conversation.

  • Wolfgang Riedmann
  • Wolfgang Riedmann's Avatar Topic Author
  • Offline
More
1 year 11 months ago #12 by Wolfgang Riedmann
Replied by Wolfgang Riedmann on topic Named parameters or How you can simplify your code
Hi Karl,

thank you very much - you have expressed very well what I think! For me it is very important to be able to read and understand my code very fast, and the hungarian notation helps me a lot.

Wolfgang

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago #13 by Robert van der Hulst
Replied by Robert van der Hulst on topic Named parameters or How you can simplify your code
Karl,

The quote style centers. You have omitted the endquote tag.

Robert

XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago #14 by Karl Faller
Replied by Karl Faller on topic Named parameters or How you can simplify your code

Robert van der Hulst wrote: Karl,

The quote style centers. You have omitted the endquote tag.

Robert

Ups, probably deleted a bit to much ;-)
Albeit, when looking nearer, any reason for the centering? Can't see much usefullness...
THX

Please Log in or Create an account to join the conversation.

More
1 year 11 months ago #15 by Robert van der Hulst
Replied by Robert van der Hulst on topic Named parameters or How you can simplify your code

Karl Faller wrote:

Robert van der Hulst wrote: Karl,

The quote style centers. You have omitted the endquote tag.

Robert

Ups, probably deleted a bit to much ;-)
Albeit, when looking nearer, any reason for the centering? Can't see much usefullness...
THX


No not really, so I have changed it.

Robert

XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.