Home > c/c++, nerdcore > Programming Language Rant

Programming Language Rant

November 15th, 2011 Leave a comment Go to comments

From http://www.esm.psu.edu/~ajm138/fortranexamples.html:

C programmers love to gloat that recursion can not be done in Fortran. When they say Fortran, they mean FORTRAN 77, since they absolutely refuse to acknowledge the existence of modern Fortran 90. (Fortran 90 came out over ten years ago. You would think they might know something about it by now!) But this example shows that even in FORTRAN 77 one can quickly and easily write routines that are recursive. So stick that in your complex variables, C programmers, and — oh wait, I forgot there are no complex variables in C. You have to manually define a complex data type. Not to mention having to write math functions like sin( ) and cos( ) to handle such data types.

Hahaaa … love it!

Categories: c/c++, nerdcore Tags: , ,
  1. November 15th, 2011 at 14:40 | #1

    Du willst doch jetzt nicht erzählen, dass Fortran eine tolle Programmiersprache ist?

    Quicksort:
    Fortran:

    ! ***********************************
    ! *
      Subroutine Qsort(X, Ipt)
    ! *
    ! ***********************************
    ! * Sort Array X(:) in ascendent order 
    ! * If present Ipt, a pointer with the 
    ! * changes is returned in Ipt.
    ! ***********************************
     
        Type Limits
           Integer :: Ileft, Iright
        End Type Limits
     
        ! For a list with Isw number of elements or
        ! less use Insrt
        Integer, Parameter :: Isw = 10
     
        Real (kind=4), Intent (inout) :: X(:)
        Integer, Intent (out), Optional :: Ipt(:)
     
        Integer :: I, Ipvn, Ileft, Iright, ISpos, ISmax
        Integer, Allocatable :: IIpt(:)
        Type (Limits), Allocatable :: Stack(:)
     
     
        Allocate(Stack(Size(X)))
     
        Stack(:)%Ileft = 0
        If (Present(Ipt)) Then
           Forall (I=1:Size(Ipt)) Ipt(I) = I
     
           ! Iniitialize the stack
           Ispos = 1
           Ismax = 1
           Stack(ISpos)%Ileft  = 1
           Stack(ISpos)%Iright = Size(X)
     
           Do While (Stack(ISpos)%Ileft /= 0)
     
              Ileft = Stack(ISPos)%Ileft
              Iright = Stack(ISPos)%Iright
              If (Iright-Ileft <= Isw) Then
                 CALL InsrtLC(X, Ipt, Ileft,Iright)
                 ISpos = ISPos + 1
              Else
                 Ipvn = ChoosePiv(X, Ileft, Iright)
                 Ipvn = Partition(X, Ileft, Iright, Ipvn, Ipt)
     
                 Stack(ISmax+1)%Ileft = Ileft
                 Stack(ISmax+1) %Iright = Ipvn-1
                 Stack(ISmax+2)%Ileft = Ipvn + 1
                 Stack(ISmax+2)%Iright = Iright
                 ISpos = ISpos + 1
                 ISmax = ISmax + 2
              End If
           End Do
     
        Else
     
           ! Iniitialize the stack
           Ispos = 1
           Ismax = 1
           Stack(ISpos)%Ileft  = 1
           Stack(ISpos)%Iright = Size(X)
     
           Allocate(IIpt(10))
           Do While (Stack(ISpos)%Ileft /= 0)
    !          Write(*,*)Ispos, ISmax
     
              Ileft = Stack(ISPos)%Ileft
              Iright = Stack(ISPos)%Iright
              If (Iright-Ileft <= Isw) Then
                 CALL InsrtLC(X, IIpt, Ileft, Iright)
                 ISpos = ISPos + 1
              Else
                 Ipvn = ChoosePiv(X, Ileft, Iright)
                 Ipvn = Partition(X, Ileft, Iright, Ipvn)
     
                 Stack(ISmax+1)%Ileft = Ileft
                 Stack(ISmax+1) %Iright = Ipvn-1
                 Stack(ISmax+2)%Ileft = Ipvn + 1
                 Stack(ISmax+2)%Iright = Iright
                 ISpos = ISpos + 1
                 ISmax = ISmax + 2
              End If
           End Do
           Deallocate(IIpt)
     
        End If
     
        Deallocate(Stack)
     
        Return
     
      CONTAINS
     
        ! ***********************************
        Integer Function ChoosePiv(XX, IIleft, IIright) Result (IIpv)
        ! ***********************************
        ! * Choose a Pivot element from XX(Ileft:Iright)
        ! * for Qsort. This routine chooses the median
        ! * of the first, last and mid element of the 
        ! * list.
        ! ***********************************
     
          Real (kind=4), Intent (in) :: XX(:)
          Integer, Intent (in) :: IIleft, IIright
     
          Real (kind=4) :: XXcp(3)
          Integer :: IIpt(3), IImd
     
          IImd = Int((IIleft+IIright)/2)
          XXcp(1) = XX(IIleft)
          XXcp(2) = XX(IImd)
          XXcp(3) = XX(IIright)
          IIpt = (/1,2,3/)
     
          CALL InsrtLC(XXcp, IIpt, 1, 3)
     
          Select Case (IIpt(2))
          Case (1)
             IIpv = IIleft
          Case (2)
             IIpv = IImd
          Case (3)
             IIpv = IIright
          End Select
     
          Return
        End Function ChoosePiv
     
        ! ***********************************
        Subroutine InsrtLC(XX, IIpt, IIl, IIr)
        ! ***********************************
        ! * Perform an insertion sort of the list 
        ! * XX(:) between index values IIl and IIr.
        ! * IIpt(:) returns the permutations
        ! * made to sort.
        ! ***********************************
     
          Real (kind=4), Intent (inout) :: XX(:)
          Integer, Intent (inout) :: IIpt(:)
          Integer, Intent (in) :: IIl, IIr
     
          Real (kind=4) :: RRtmp
          Integer :: II, JJ, IItmp
     
     
          Do II = IIl+1, IIr
             RRtmp = XX(II)
             Do JJ = II-1, 1, -1
                If (RRtmp < XX(JJ)) Then
                   XX(JJ+1) = XX(JJ)
                   CALL Swap_IN(IIpt, JJ, JJ+1)
                Else
                   Exit
                End If
             End Do
             XX(JJ+1) = RRtmp
          End Do
     
          Return
        End Subroutine InsrtLC
     
      End Subroutine Qsort
     
    ! ***********************************
    ! *
      Integer Function Partition(X, Ileft, Iright, Ipv, Ipt) Result (Ipvfn)
    ! *
    ! ***********************************
    ! * This routine arranges the array X
    ! * between the index values Ileft and Iright
    ! * positioning elements smallers than
    ! * X(Ipv) at the left and the others 
    ! * at the right.
    ! * Internal routine used by Qsort.
    ! ***********************************
     
        Real (kind=4), Intent (inout) :: X(:)
        Integer, Intent (in) :: Ileft, Iright, Ipv
        Integer, Intent (inout), Optional :: Ipt(:)
     
        Real (kind=4) :: Rpv
        Integer :: I
     
        Rpv = X(Ipv)
        CALL Swap(X, Ipv, Iright)
        If (Present(Ipt)) CALL Swap_IN(Ipt, Ipv, Iright)
        Ipvfn = Ileft
     
        If (Present(Ipt))  Then
           Do I = Ileft, Iright-1
              If (X(I) <= Rpv) Then
                 CALL Swap(X, I, Ipvfn)
                 CALL Swap_IN(Ipt, I, Ipvfn)
                 Ipvfn = Ipvfn + 1
              End If
           End Do
        Else
           Do I = Ileft, Iright-1
              If (X(I) <= Rpv) Then
                 CALL Swap(X, I, Ipvfn)
                 Ipvfn = Ipvfn + 1
              End If
           End Do
        End If
     
        CALL Swap(X, Ipvfn, Iright)
        If (Present(Ipt)) CALL Swap_IN(Ipt, Ipvfn, Iright)
     
        Return
      End Function Partition
     
    ! ***********************************
    ! *
      Subroutine Swap(X, I, J)
    ! *
    ! ***********************************
    ! * Swaps elements I and J of array X(:). 
    ! ***********************************
     
        Real (kind=4), Intent (inout) :: X(:)
        Integer, Intent (in) :: I, J
     
        Real (kind=4) :: Itmp
     
        Itmp = X(I)
        X(I) = X(J)
        X(J) = Itmp
     
        Return
      End Subroutine Swap
     
    ! ***********************************
    ! *
      Subroutine Swap_IN(X, I, J)
    ! *
    ! ***********************************
    ! * Swaps elements I and J of array X(:). 
    ! ***********************************
     
        Integer, Intent (inout) :: X(:)
        Integer, Intent (in) :: I, J
     
        Integer :: Itmp
     
        Itmp = X(I)
        X(I) = X(J)
        X(J) = Itmp
     
        Return
      End Subroutine Swap_IN
    

    Ruby:

    def quicksort(v)
       return v if v.nil? or v.length <= 1
       less, more = v[1..-1].partition { |i| i < v[0] }
       quicksort(less) + [v[0]] + quicksort(more)
    end
    

    Erlang:

    qsort([]) -> [];
    qsort([Pivot|Rest]) ->
        qsort([ X || X <- Rest, X < Pivot]) ++ [Pivot] ++ qsort([ Y || Y = Pivot]).
    
  2. jens
    November 17th, 2011 at 00:14 | #2

    @jupp
    Ich weiß nicht was du hast, aber mein qsort hat nicht mal 30 Zeilen:
    program qsort
    implicit none
    real(kind=4), dimension(6) :: array = (/ 2, 21, 3, 44, -5, 6 /)
    call quicksort(array, 6)
    write(*,*) array
    contains
    recursive subroutine quicksort(array, asize)
    integer :: asize, i, x, y
    real(kind=4) :: array(asize), less(asize), greater(asize), pivot
    if( asize .le. 1 ) then
    return
    end if
    pivot = array(asize/2)
    x=0
    y=0
    do i=1, asize
    if( array(i) .le. pivot .and. i .ne. asize/2 ) then
    x = x + 1
    less(x) = array(i)
    else if ( i .ne. asize/2 ) then
    y = y + 1
    greater(y) = array(i)
    end if
    end do
    call quicksort(less(1:x), x)
    call quicksort(greater(1:y), y)
    array(1:asize) = (/less(:x), pivot, greater(:y)/)
    end subroutine
    end program

    Kann dein Ruby/Erlang auch sowas wie:
    C = matmul(A, B)
    Nu hab ichs dir aber gezeigt 😛

    Ich glaub nicht dass irgendeine Programmiersprache/Programmierer sich rausnehmen sollte, die anderen (Sprachen) runter zu machen, weil sie eventuell schlechter wären. Es sind schließlich keine Religionen.

  3. November 17th, 2011 at 15:25 | #3

    @jens

    Das Beispiel war aus http://en.wikibooks.org/wiki/Algorithm_Implementation/Sorting/Quicksort

    Es geht auch nicht darum, irgendwelche Funktionen zu callen, wie das matmul-beispiel sondern den Algorithmus from scratch zu implementieren. Da hat sich in den letzten 30 Jahren manches getan bei den Programmiersprachen 🙂 Quicksort ist natürlich ein gemeines Beispiel, aber es steht ja auch rant über Robins Post und da darf man doch mal ein bisschen trollen.

  4. jens
    November 18th, 2011 at 04:46 | #4

    @jupp
    Schon klar. Ich wollte auch nur zeigen dass das Beispiel etwas zu lang war. Aber beim “from scratch” muss ich dir wiedersprechen, das matmul() ist keine Funktion, sondern Teil des Fortran Standard, also in meinen Augen “from scratch”, oder siehst du das anders?

  1. No trackbacks yet.