Archiv der Kategorie: IT

Älterer Mann, neue Tricks

Sieht so aus, als ob ein alter weißer Mann auch noch neue Tricks lernen kann.

Und das “locker” nach mehr als 20 Jahren Emacs – Nutzung Man gewöhnt sich an E(sp)M(eta)A(lt)C(ontrol)S(hift), aber man liest auch immer wieder, daß bei typischen Editor Aufgaben die vi Nutzer schneller ans Ziel kommen, und man ist versucht, es damit aufzunehmen und voilà Evil -mode was born . Genau das liebe ich so an der Programmierung, es ist ernst, aber man macht sich lustig, entweder über Andere (wie b… kann man sein es so zu schreiben/implementieren) oder sich selber wie b … kann man sein so einen Bock einzubauen.

Ich denke nach so langer Zeit gebe ich DoomEmacs eine Chance, es ist etwas dabei, was ich gleich super fand, und zwar die doc. Wie super man das aufbauen kann, man erkennt es erst, wenn man es sieht, man ist wirklich betriebsblind, das hätte man sicher schon vor langer, langer, sehr langer Zeit selber implementieren können. Aber dafür hätte man …

Ja, ja hätte, hätte …

Was mir daran so gut gefällt?

Einfach

erst mal wird klargestellt um was es geht, aber dann gleich wo man es findet und dorthin wird verlink! Wow!

Dann kommt die signature (also wie man das Ding benutzt)

dann die Dokumentation und die ist bei allen Emacs-Lisp Funktionen mit dabei:

Dann gibt es ein Verlinken in das Handbuch und es wird besser

Es gibt einen Link find All references (also überall im ganzen Editor wo es gesucht wird kann man es sehen … irre)

Und alles mit Links draufklicken oder draufgehen und RET -> man ist da. Das ist so fantastisch. Integriert, das kann man wohl sagen …

Wird sich das umlernen bezahlt machen mal sehen im Zweifel bleibt einem immer noch C-z 😉 Wer auch immer dort draußen den Emacs benutzt, ich denke es lohnt sich einen genaueren Blick auf DoomEmacs zu werfen …

Sieht so aus

Als ob ich zum Ende meiner Refaktorierung komme. Es scheint, ich konnte 4 verschiedene Formulare mit 4 verschiedenen Abfragen auf 1 Form mit 1 Abfrage umprogrammieren. Es ist IMHO hilfreich, das Wissen was man hat, in Objekten/Strukturen unterzubringen. Der Code ist bislang nicht perfektioniert, aber immerhin statt 4 Formen mit Code von 120 Zeilen ist es nur noch eine Form mit rund 140 +/- 20 Zeilen.

So sieht der ersetzte Code aus:

'Dim intAntwort As Integer
'Dim strNeueZeile As String
'strNeueZeile = Chr$(10) & Chr$(13)
'
'Dim intSchleife As Integer
'Dim lngNr As Long
'Dim lngDrucker As Long, strBericht As String
'
'Dim WSP1 As Workspace, DB1 As Database, Tabelle1 As Recordset
'Set WSP1 = DBEngine.Workspaces(0)
'Set DB1 = WSP1.OpenDatabase(strDatenbankGlo)
'
'Set Tabelle1 = DB1.OpenRecordset("HT_Nummernkreise", DB_OPEN_TABLE)     ' Tabelle öffnen.
'
'If Forms!HF_AuftrAnkErz!AngebotKz = True Then
'    ' Rückfrage mit Speicherung der Antwort
'    intAntwort = MsgBox("Für diesen Auftrag wurde bereits ein Angebot gedruckt!" & strNeueZeile & "Wollen Sie diesen Ausdruck wiederholen?", 33, "Angebot drucken?")
'    If intAntwort = 2 Then
'        GoTo Exit_DruckAngebot_Click
'    End If
'End If
'
'' Firma Beller
'If strKundeNr = "143" Then
'    strBericht = "BR_DruckAngebotAnkErz_Bel"
'Else
'    strBericht = "BR_DruckAngebotAnkErz"
'End If
'
'ordneDruckerZu "Angebot", strBericht, HAUPT_DRUCKER
'
'' Prüfen ob Kontrollkästchen für Seitenansicht aktiviert
'' wenn aktiviert dann Seitenansicht, ansonsten Ausdruck auf Drucker
'If Me!Seitenansicht = True Then
'    DoCmd.OpenReport strBericht, acViewPreview
'Else
'    Tabelle1.MoveLast                     ' Letzten Datensatz suchen.
'    setzeFelder Forms!HF_AuftrAnkErz, Tabelle1, DRUCK_BEREICH_ANGEBOT
'    erhoeheNummer Tabelle1, "AngebotNr"
'
'    Forms!HF_AuftrAnkErz!AngebotKz = True   ' Setzen der Druckkennziffer
'    Forms!HF_AuftrAnkErz.Refresh
'
'    ' Logbucheintrag
'    If DLookup("[Benutzerverwaltung]", "HT_SysParameter") = True Then
'        Call SetzeBenutzerLog("Drucke Angebot m. Summen Ankauf Erz.-Preis! Auftrag Nr: " & CStr(Forms!HF_AuftrAnkErz!AuftragNr) & ", Angebot Nr: " & CStr(Forms!HF_AuftrAnkErz!AngebotNr))
'    End If
'End If

Also grob 4 * 120 = 480 (es kommen wahrscheinlich noch ein paar Zeilen dazu, wegen eines Berichts, der genau auf die Anforderungen eines Kunden zugeschnitten war, die Logik ändert sich aber nicht, auf, sagen wir mal 160 LOC, 60 – 70 % weniger Code. Macht bei 500 000 Loc rund 600 / 500 000 * 100 = 0,12 % 😉 und 3 Formulare weniger … Nicht beeindruckend, wenn man aber betrachtet, in wie vielen Bereichen man das erreichen könnte. Wäre eine erste Schätzung, daß man den Code auf 160 / 600 = 26,6 % runter brächte, was dann auf gerade mal 125 000 Zeilen von Code hinausliefe, ohne Einbußen bei der Funktionalität. Wenn man dann noch die extrem aufwendige Übergabe an diverse Buchhaltungssysteme auf Datev herunterschraubte (was wohl jede Fibu in D einlesen kann) … Da kann man mal sehen, was nur eine andere Strukturierung an Vorteilen brächte und wie viel weniger Fehler gäbe es und wie viel einfacher wäre eine Korrektur? Sollte ich mal einen Fehler in den Angeboten finden, bräuchte ich nur eine Methode ändern statt … Mal sehen wie’s weitergeht. Es kommt wohl etwas dazu, weil es das Ziel ist, alle Reports auch als Email versenden zu können. Mal schauen…

Passend zu den letzten Einträgen

Ich schrieb, daß ich mich auf einen neuen Trip begebe, ich möchte anfangen F# intensiver zu benutzen. Ich hole noch ein bisschen aus, um meinen Hintergrund zu verstehen. Ich bin a) nicht mehr der Jüngste und b) ca 30 Jahre Programmierer +/- 10 Jahre. Die 10 Jahre kommen von meinen “leichten” Kontakten zur Programmierung. Weil es beim Bund für Wehrpflichtige die Möglichkeit gab, Kurse zu belegen, habe ich bei einem dBase Kurs mitgemacht. OS: CPM und dBase II Bildschirm vielleicht 80 x 24 Zeichen, ich weiß es nicht mehr. Eines meiner ältesten Bücher aus der Zeit ist vom Franzis Verlag, Titel Die beiden Datenbanksysteme dbase II und III, Datum im Buch 1986.
Das ergibt 2022 – 1986 = 36 Jahre, tja und in der Schule habe ich auf einem TI irgendwas mit Basic angefangen. Somit ja das mit der Zeit kommt hin. Dann kam der erste PC in ‘s Haus. Ein Atari ST , RAM 1024 MB , Platte 20 MB!, sauteuer aber cool. Da ein wenig in die Programmierung reingeschnuppert, aber nie was auf die Reihe bekommen. Dann kam das Studium an der Uni Karlsruhe und der erste Kurs war Modula-2. Ich habe bisher nichts öfter wiederholt als diesen Kurs. Ich bin, was programmieren angeht, kein schneller Lerner, aber hartnäckig nehme ich an. Der Kurs war irgendwann geschafft und dann kam C und keine Ahnung, von da an lief es, was programmieren angeht besser. Absurd, wenn man daran denke wie viele lesbarer Modula-2 Code ist als C (wenn man es nicht gewohnt ist). Trotzdem scheint es für mich leichter gewesen zu sein Den Kurs habe ich sofort bestanden. Dann kam Eiffel und darin habe ich angefangen ernsthaft Software zu schreiben. Es gibt noch ein paar Paket dort draußen in denen ich meine Finger reinsteckte siehe: https://fam-dominicus.de/tiki/tiki-index.php?page=FriedrichsTiki . Vielleicht sollte ich die Quellen mal irgendwan zugänglich machen.

Dann gründete ich die Q-Software Solutions und die Idee war ursprünglich eine Nachfolgersprache für Eiffel zu entwickeln Q. Die Idee damals: strikte Trennung CQS. Der Teil mit Status sollte OO mässig aufgebaut sein, der Rest funktional. Naja wir hatten etwas was prinzipiell funktioniert aber es war ein totaler wirtschaftlicher Reinfall, es wurde nie fertig und verschlang wirklich viel Geld ….

Hier noch ein bisschen Code der damals lief …


https://fam-dominicus.de/tiki/tiki-index.php?page=FriedrichsTiki
class Argv_test -- Main

creation
   make
      local
         i : Integer;
         args: Arguments;
      do
         args := new Arguments.make;
         out := new Standard_output;
         i := 1;
         loop
         until i > args.argument_count
            out.print_string("argument ");
            out.print_integer(i);
            out.print_string("= ");
            out.print_mutable_string(args.argument(i));
            out.print_newline;
            i := i + 1;
         endloop
         out.print_string("program name = ");
         out.print_mutable_string(args.program_name);
         out.print_newline;
      end;

public


   out: Standard_output;


endclass

Es compilierte nach C und deswegen habe ich mich mit Jacob Navia zusammengetan.( https://lcc-win32.services.net/. Die Zusammenarbeit war lang und erfreulich. Und nun gebe ich ein wenig an, wir waren unter den Ersten, die diesen Compiler auf 64-bit portierten, damals für eine Firma, die das benutzen wollte, um SQL Queries für ihre Datenbank zu kompilieren. Es gab auch eine Firma, die ein 5-GL Sprache anbot, die nach C kompilierte, das C war lcc-win32. Ich glaube die Schnittstelle nach C von Q war eine der einfachsten, die es damals gab und vielleicht heute noch gibt:

Da kam also einiges an Erfahrung mit C dazu. Es ist heute immer noch eine PS, die ich schätze. Aber PS haben einen “leicht” addiktiven Effekt und ja, die Idee von Q ist immer noch präsent. Über die Zeit habe ich mir dann immer mehr PS angeschaut, manche angeeignet, einige relativ umfassend, andere so la la und manche eher schlecht als recht.
Ich zähle einfach nur auf (ohne zu sagen wie gut oder schlecht ich damit zurecht komme) , C, Eiffel, Turbo Pascal, Perl, Tcl/Tk, Ruby, Python, Common Lisp, Scheme, Smalltalk, D, Java, C#, Emacs Lisp, Erlang, Racket, IO, Self, Dylan, Ocaml, div. Assembler, VBA, WLanguage, C##

Man sieht, eher auf der OO Seite, wie ich aber vor zwei Tagen schrieb ist mir Java und C# irgendwo zu “verbose”, ich muß zuviel schreiben und lesen um zum Kern zu kommen, deshalb denke ich werde ich mit F# auf .NET gut fahren. Wie geschrieben, ich denke, man sollte alle Hilfe beim Programmieren benutzen, derer man habhaft werden kann. Es gibt aber ein paar Sprachen, in denen ich mir zutraue, etwas hinzubekommen, die ich aber nicht mag und ganz oben sind da C++ und Perl. Die sind IMHO zu kompliziert, aber ich kann weit daneben liegen.
Ich warte derzeit eine Software seit mehr als 10 Jahren, eine MS-Access Lösung. Sie funktioniert, ist aber ein Ärgernis, was Wartung und Weiterentwicklung angeht. Ich arbeite daran, aber …

Also wohin und was tun. Ich denke nach dem Abwägen der Möglichkeiten und der eigenen Vorlieben und Können sollte ich mit F# durchaus zurande kommen. Auf der anderen Seite sehe ich dann Videos wie:


Was mich einfach abschreckt und das sieht für mich nach kompliziert aus, ohne einen Gegenwert. Ich denke, ich möchte keine manuelle Speicherwaltung und ich möchte mich nicht mit Referenzen und Eigentum von Objekten auseinandersetzen. Ich möchte eine einfach lesbare Lösung und Sprache und F# könnte es sein. Ich denke auch die Trennung von OO und FP dürfte in F# funktionieren und wenn’s nicht klappt, kann ich immer noch C# Klassen benutzen 😉

Zum letzten Eintrag

Ich schrieb ja, ich werde mich auf einen neuen Trip begeben und F# intensiver nutzen.
Heute habe ich auf chatgpt+ geupdated und ich denke es werden gut angelegte 25 € im Monat sein. Zumindest hat es mir schon mal geholfen, einen Code zu erstellen, den ich heute wohl noch verwenden werde. Das hielt ich daher auf FB fest:

Ich habe mich etwa intensiver mit chatgpt beschäftigt und ich weiß, man sollte mit Superlativen vorsichtig sein. Ich denke aber das wird mein Programmiererleben und das der zukünftigen Programmierer mindestens genauso verändern wie die Suchmaschinen im WWW.

Ich sehe, es in den vielen youtube Videos, die meisten benutzen nicht man etwas wie `man` sondern tippen es gleich in die Suchmaschine ein und kopieren dann den Code in 0, nichts.

Es ist absolut hilfreich, wenn man sich in neue PS einarbeitet und der Code ist m.E. von guter Qualität, und wenn er dann noch gleich kompiliert und läuft ist es “nur” der Punkt auf dem i 😉

Betrachten wir die Vergangenheit haben Maschinen massiv dazu beigetragen, die Produktion zu erhöhen und wir leben in derartig guten Zuständen (auch wenn es klar durch die Irren in der Politik in die falsche Richtung geht) dank der Mechanisierung. Ich denke durch Maschinen wie chatgpt können wir so etwas auch für die Programmierung sehen. Ich weiß noch nicht, wie und ob sich die Codequalität ändern wird, ich tippe auf eine Verbesserung, aber auch auf mehr Duplizierung in Code – mal sehen. Ein paar Jahre habe ich ja noch … (wahrscheinlich)

Ich denke, für Programmierer wird es auf erfreuliche Weise interessant

FD auf FB (FD = Friedrich Dominicus)

Ich glaube, ich gehe auf ‘nen Trip

Mit einer von mir bisher wenig gebrauchten PS. Ocaml aka F#. Warum? Nun ich würde gerne Smalltalk benutzen, aber ich möchte auch so viel wie möglich Compilerunterstützung gegen Typos und andere Fehler nutzen. Ich denke mir, was der Computer testen kann, soll er auch testen. Ich mag es weiterhin nicht, mich zu wiederholen, als wäre ich eine gesprungene Schallplatte:

LongPathToSomeJavaClass<withTemplate1, withTemplate2> = myClass = new LongPathToSomeJavaClass<withTemplate1, withTemplate2>()

Ja, ich weiß, man braucht es nach dem New nicht mehr so zu schreiben. Was mir auch nicht so gefällt, wenn ich die Methoden in OO-Weise aufliste MyList.map(some function).filter(someCondition) …

Und ja, seiteneffektfreie Funktionen sind auch schön zu haben. IM Vergleich sieht
F# so aus:

let mutable i = 1
in
    let rec loop() =
        printf "i= %d >" i 
        let input = Console.ReadLine()
        if input = "exit" then 
            exit(0)
        else 
            printfn "You typed: %s" input
            i <- i + 1
            loop()


loop()

Es ist typsicher, ohne dass man es deklarieren muß. Man kann aber:
Also kann ich auch schreiben let mutable i:int = 1. Auf der anderen Seite ist e s nicht so jerkish wie Haskell: http://learnyouahaskell.com/input-and-output.

Ich finde, man kann es ziemlich “locker runter lesen – und verstehen. Mir gefällt vor allem auch ein Schlüsselwort wie ‘mutable’, damit teilt man F# mit, hey ich werde das ändern und man macht es dann einfach (i <- i+1)

Und vor allem mag ich es, wenn man Daten auch in Objekte packen kann, mit Polymorphismus (die Haskellianer verstehen etwas anderes als der Rest der Welt darunter) . Ich sehe hier wirklich eine Obermenge von Programmerweisen.

  1. Simpel und “dumm” prozedural let a … let b let c
  2. funktional (keine Seiteneffekte, keine Überraschungen bei Aufruf von Funktionen
  3. objektorientiert (da kenne ich mich nun mal am besten aus und mir kommt es in meinem Programm am weitesten entgegen.

Ich schrieb ja oben von Smalltalk, ich kann viel von OCaml auch in Smalltalk bekommen (schließlich sind Blöcke nicht anderes als Funktionen. Aber nichts warnt mich während der Entwicklung ,wenn so was passiert (pseudo code)


aHouse := aCrodocile
.
.
.
aHouse openDoor. 

Ja, die IDES werden einen vielleicht warnen, aber im Endeffekt, wird uns zur Laufzeit mitgeteilt, da liegst’e mit dem Typ aber daneben. Das kann einem in Ocaml, F# und Haskell nicht passieren. Weithin passt F# komplett in die .NET Welt. Mir wäre kein Smalltalk bekannt, für das das gilt, ja es gab mal ich glaube IronSmalltalk oder so, aber AFAIK gibt es derzeit keine Unterstütztes auf Windows. Ich glaube eine Kombination in einer Sprache, die einen nicht bevormundet ist eine der besten Lösungen. Ich werde mal sehen, wohin mich dieser Trip führt, vielleicht liege ich falsch.

Es wäre nicht das erste Mal und nicht das letzte Mal. Ich werde mal sehen wie’s läuft und ich denke, man kann in diesem Blog auch nachlesen, wenn ich meine Meinung zu etwas geändert habe. Vielleicht passiert es wieder mit F#, vielleicht auch nicht …

Für mich als Einzelprogrammierer gibt es ein paar Wege. Ich kann wie Millionen von andere auf die großen Spieler setzen, ich kann etwas nehmen, was für meinen Bereich am besten zu gebrauchen ist und ich kann nehmen, was mir eher gefällt und auch wenn ich es von Eiffel anders kenne, sehe ich durchaus einen Punkt in dem Sprichwort: “In der Kürze liegt die Würze”

Man kann den Code ja mal in Java, C# oder C++ programmieren und schauen, wie es dann aussieht …

Meistens geht es hier um Politik

Speziell, wie wahnsinnig und menschenverachtend die inzwischen geworden ist.

Es ist aber nicht mein einziges Steckenpferd ;-). Es klang sicher schon gelegentlich an, daß ich Programmierer bin. Ich pflege seit mehr als 10 Jahren eine Branchenlösung für Abfallbetriebe, Containerdienste. Das Ganze ist für kleine Betriebe mit weniger als sagen wir mal 5 AP für die EDV. Das sind nach meinem Wissen so ca maximal so um die 50 Leute die mit der Software bedient werden. Die meisten Dateneinträge dürften Wiegungen sein. Für jede komplette Wiegung braucht es, so gut wie immer zwei Wiegungen. Ich denke, die Software wurde schon zu DOS Zeiten entwickelt, vielleicht liege ich damit aber auch schief. Wie auch immer, die Programmiere haben m.E. a) relativ typisch in MS Access programmiert und b) wenig über die Menge an Code nachgedacht. Im Zweifel lief es wohl so. Da läuft was, wir kopieren es und passen es halt an. So gibt es Redundanzen noch und nöcher, aber natürlich nicht komplett, das wäre ja zu einfach. Wo man die Redundanzen sehr gut sehen kann, ist an folgendem Code:

Private Sub DruckAngeboSum_Click()
On Error GoTo Err_DruckAngeboSum_Click

Dim objOut As CMediaOutput
    
    Set objOut = generateMediaOutputObjects(ActiveControl.Name)
    objOut.doOutput

'Dim intAntwort As Integer
'Dim strNeueZeile As String
'strNeueZeile = Chr$(10) & Chr$(13)
'
'Dim intSchleife As Integer
'Dim lngNr As Long
'Dim lngDrucker As Long, strBericht As String
'
'Dim WSP1 As Workspace, DB1 As Database, Tabelle1 As Recordset
'Set WSP1 = DBEngine.Workspaces(0)
'Set DB1 = WSP1.OpenDatabase(strDatenbankGlo)
'
'Set Tabelle1 = DB1.OpenRecordset("HT_Nummernkreise", DB_OPEN_TABLE)     ' Tabelle öffnen.
'
'If Forms!HF_AuftrAnkErz!AngebotKz = True Then
'    ' Rückfrage mit Speicherung der Antwort
'    intAntwort = MsgBox("Für diesen Auftrag wurde bereits ein Angebot gedruckt!" & strNeueZeile & "Wollen Sie diesen Ausdruck wiederholen?", 33, "Angebot drucken?")
'    If intAntwort = 2 Then
'        GoTo Exit_DruckAngeboSum_Click
'    End If
'End If
'
'' Firma Beller
'If strKundeNr = "143" Then
'    strBericht = "BR_DruckAngebotAnkErzoSum_Bel"
'Else
'    strBericht = "BR_DruckAngebotAnkErzoSum"
'End If
'
'ordneDruckerZu "Angebot", strBericht, HAUPT_DRUCKER
'
'' Prüfen ob Kontrollkästchen für Seitenansicht aktiviert
'' wenn aktiviert dann Seitenansicht, ansonsten Ausdruck auf Drucker
'If Me!Seitenansicht = True Then
'    If strKundeNr = "143" Then
'        strBericht = "BR_DruckLiefschAuftrAnkErzNot_Bel"
'    Else
'        strBericht = "BR_DruckLiefschAuftrAnkErzNot"
'    End If
'    DoCmd.OpenReport strBericht, acViewPreview
'Else
'    Tabelle1.MoveLast ' Letzten Datensatz suchen.
'    setzeFelder Forms!HF_AuftrAnkErz, Tabelle1, DRUCK_BEREICH_ANGEBOT
'    erhoeheNummer Tabelle1, "AngebotNr"
'
'
'    druckeBericht "Angebot", strBericht, Me!AnzahlDrucke
'
'
'    Forms!HF_AuftrAnkErz!AngebotKz = True   ' Setzen der Druckkennziffer
'    Forms!HF_AuftrAnkErz.Refresh
'
'    ' Logbucheintrag
'    If DLookup("[Benutzerverwaltung]", "HT_SysParameter") = True Then
'        Call SetzeBenutzerLog("Drucke Angebot o. Summen Ankauf Erz.-Preis! Auftrag Nr: " & CStr(Forms!HF_AuftrAnkErz!AuftragNr) & ", Angebot Nr: " & CStr(Forms!HF_AuftrAnkErz!AngebotNr))
'    End If
'End If
  
Exit_DruckAngeboSum_Click:
    On Error Resume Next
'    Tabelle1.Close
'    DB1.Close
    Exit Sub

Err_DruckAngeboSum_Click:
    If err = 2501 Then
        Me!Schließen.SetFocus
    Else
        MsgBox Error$
    End If
    Resume Exit_DruckAngeboSum_Click

End Sub

Die drei Zeilen Code oder so sind das was nach dem Überarbeiten bleibt.
Ein paar Dinge dürften Programmierer in neueren Sprachen durchaus verunsichern, das sind die Label zu denen man springt. Ja, das kann man inzwischen anders lösen und nein, es ist recht typisch für VBA. Man sieht, nur für die Fehlerbehandlung kommen “locker” 5- 10 Zeilen Code zu jeder Funktion. Insgesamt sind es über 500 000 Zeilen an Code und viele Methoden gehen über mehrere Seiten.

Wie man sehen kann, gibt es keine Trennung der Bereiche. In einer Methode/Funktion gibt es Zugriffe auf die Datenbank, Manipulation der UI und Interaktion mit dem Benutzer. Ich befürchte, daß ist immer noch Stand der Dinge bei sehr vielen Access Programmen. Als wirklich ernsthaftes Problem sehe ich das Fehlen von brauchbaren Testmöglichkeiten an. AFAIK gibt es AccUnit zum Testen, das bekomme ich hier nicht installiert und ich bin derzeit immer noch zu faul um mich dahinterzuklemmen.

Die Klasse, in der ich es auslagerte, sieht der Code nun so aus:

Public Sub doOutput()
    Dim bAdjustNumber As Boolean
    Dim objControl As CControlNummernKreise
    
    

On Error GoTo HandleError
    Dim iAuswahl As Integer
    If outputMedia = outMediumPreview Then
        outputPreview
        GoTo HandleExit
    End If
    
    
    bAdjustNumber = True
    If NZ(actForm(textFieldNumberName), "") <> "" Then
        iAuswahl = askToReprintIfPrintedBefore()
        If iAuswahl = vbNo Then
            GoTo HandleExit
        Else
            bAdjustNumber = False
        End If
    End If
   
    Set objControl = actualizeFormDataBeforePrint()
         actualizeNumberCircle objControl, bAdjustNumber
         Set objControl = Nothing
        
         actionBeforePrint
             If outputMedia = outMediumPrinter Then
                 outputPrinter
             Else
                 outputEmail
             End If
         actionAfterPrint
    actualizeFormDataAfterPrint
    writeLog

    
    
HandleExit:
    On Error Resume Next
    Exit Sub


HandleError:
    If err.Number <> 0 Then
       MsgBox "Error " & err.Number & " (" & err.Description & ") in procedure doOutput."
    End If
    GoTo HandleExit


End Sub

Sicher noch reichlich zu kritisieren, aber ich denke, eine Verbesserung ist zu erkennen.
Der Witz an dieser einen Methode ist: Die kann ich so an ungefähr 8 Stellen so benutzen und muß da nichts mehr anfassen. Ich muß die Daten entsprechend vorbelegen

Case FRM_AUFTRAG_ANKAUF_ERZ
If sKundeNr = "143" Then
objResult.reportName = "BR_DruckAngebotAnkErz_Bel"
Else
objResult.reportName = "BR_DruckAngebotAnkErz"
End If            
objResult.logEntry = "Druck Angebot Ankauf Erz. m. Summen Auftrag Nr: " & NZ(objResult.orderNo, 0) & _
                                 ", Angebot Nr: " & NZ(objResult.actForm(objResult.textFieldNumberName), "")

            objResult.lblFuerKLNr = "Lieferant Nr:"

            Set objParameterAngebot = parDruckAngebot_WH()
            objParameterAngebot.mainTableName = "HT_AuftragAnkaufErz"
            objParameterAngebot.subTableName = "UT_AuftragAnkaufErz_Positionen"
            objParameterAngebot.fieldNameKLNo = "LieferantNr"

gen, aber die Logik dieses Teils geht nicht verloren. Ich denke, daß ist einer meiner Lieblingstechniken, einen Algorithmus austüfteln und dann möglichst nicht mehr anfassen zu müssen. Sollte was schiefgehen, dann habe ich hier eine zentrale Anlaufstelle, um es zu korrigieren und muß nicht die Korrektur 8 mal wiederholen.
Leider macht es einem VBA unglaublich schwer Code wiederzuverwenden, denn obwohl das hier eine Klasse ist, kann ich nicht einfach davon ableiten und nur die Sachen umschreiben, die ich brauche. Ja, es gibt Interfaces, aber die muß man dann von a-z in allen Klassen implementieren, das ist einfach schlecht und dürfte Leuten, die mit Java, Python, Ruby oder so gut wie jeder anderen OO-Sprache programmieren, die Tränen in die Augen treiben. Die Dinge sind aber nun mal, wie sie sind. Modularer bekäme man es nur hin, wenn man jede Methode in ein eigenes Interface auslagerte und dann die Interfaces implementierte, die einzige zugängliche Methode wäre dann z.B. für

 If outputMedia = outMediumPreview Then
        outputPreview
        GoTo HandleExit
    End If

outputTo aber man müsste halt all notwendigen Daten in diesem Interface hinterlegen und bräuchte zumindest ein paar Parameter oder ein Parameter Objekt.

Dann könnte man ein Interface haben für eine Klasse mit dem Namen OutputPreview
und den Wert so setzen

objIf as OutputInterface
if Test_If_Angebot then
  set objIf = new OutputInterfaceAngebot 
...
:..

und riefe es so auf
objIf.outputTo

Es geht leider nicht anders und dann bekommt man eben auch so etwas:

Case FRM_AUFTRAG_ANKAUF_ERZ
            If sKundeNr = "143" Then
                    objResult.reportName = "BR_DruckAngebotAnkErz_Bel"
                Else
                    objResult.reportName = "BR_DruckAngebotAnkErz"
                End If
               
                objResult.logEntry = "Druck Angebot Ankauf Erz. m. Summen Auftrag Nr: " & NZ(objResult.orderNo, 0) & _
                                     ", Angebot Nr: " & NZ(objResult.actForm(objResult.textFieldNumberName), "")
                                     
                objResult.lblFuerKLNr = "Lieferant Nr:"
            
                Set objParameterAngebot = parDruckAngebot_WH()
                objParameterAngebot.mainTableName = "HT_AuftragAnkaufErz"
                objParameterAngebot.subTableName = "UT_AuftragAnkaufErz_Positionen"
                objParameterAngebot.fieldNameKLNo = "LieferantNr"

Hier muß ich einfach festhalten MS hat sich einiges bei VBA gedacht aber a) nicht zu Ende und b) mangelhaft an bestimmten Stellen.

Es gibt durchaus eine Menge Fans von Access. Vom Standpunkt von guter OO-Programmierung ist VBA ein Sanierungsfall. Dabei könnte es so einfach sein. VBA als Mitglied der .NET Sprachfamilie und gut wär’s. Ich verstehe nicht, warum es MS nicht macht. Die Unterstützung durch Werkzeuge ist so in den 80 er Jahren des letzten Jahrtausends hängen geblieben. Ja, man kann in VBA auch riesige Programme schreiben, es tut aber weh ….

Wo MS-Access (mit VBA) vollkommen mangelhaft ist
1) Keine integrierten Tests
2) An Objekten orientiert, aber nicht OO-mässig zu programmieren
3) Grauenhafte Benutzung in einem RCS (hier benutze ich TortoiseGit) , Problem: Groß/Kleinschreibung geht munter durcheinander, es gibt IDS, die sich einfach ändern
4) Keine Unterstützung für die Trennung von UI, Daten und dem Programm. Wie geschrieben, der Code ist heute noch typisch für Ms Access. Man bekommt halt schnell was zusammen …
5) der SQL Editor ist eine Zumutung!

Wo es glänzt
1) mal eben was zusammenstoppeln ist schnell erledigt
2) der Direktbereich, man kann während der Laufzeit anhalten und sich alles anschauen, kein rekompilieren nötig
3) preisgünstig

Es ist klar MS will, daß wir MS-SQL mit C# benutzen, es ist nicht überzeugend, daß dies für kleine Betriebe eine bessere Lösung als eine MS-Access basierte wäre.

Wünsche und Beschwerden …

Ziehe ich mal von FB rüber, womöglich mache ich da ja nicht mehr so lange mit …

Ich weiß, das Leben ist kein Wunschkonzert, aber trotzdem darf man Wünsche haben. Es gibt eine Reihe davon aus meinem Programmerleben:

– VBA als vollständiges Mitglied der .NET Familie, das Gleiche bitte auch für die WLanguage

– Ein vernünftiger Editor für VBA (ohne die MZ Tools wäre es noch schlechter) MS kann offensichtlich IDEs, warum nicht für die in Office benutzte PS? Man schaue sich mal OpenGenera an und den dort benutzen ZMACS, das ganze OS kann man in Lisp Dialekten programmieren.

– ein vernünftiges Test-Framework für Ms Access. Man versteht, warum es keine Tests gibt und alle Programme im Debugger “entwickelt” werden.

– Vernünftige Editoren für Smalltalks (egal welches, alle sind unkomfortabel und das für so eine wunderbare Sprache wie Smalltalk

– Ein Smalltalk für die .NET Familie

– Vernünftige GUI, Report Builder oder Tools für die Behandlung von Dateien und Verzeichnissen, für Smalltalks und spezieller Pharo. Warum gibt es nicht was zumindest Gleichwertiges in diesem Bereich zu ja selbst MS Access?

– Ein wirklich nettere PS für Latex (auch wäre ein visueller Report Builder eine nette Sache) Latex läuft, ist stabil seit mehr als20 Jahren und bringt besser Sachen aufs Papier als so gut wie jedes andere Programm .

– Ein GUI-Builder, GUI-Framework, für Emacs, damit man endlich mal auch das von der manuellen Erstellung von GUIS wegkommt.

Ganz massiv stört mich diese Sachen bei Smalltalk. Wenn das in Java möglich ist, dann schon lange in Smalltalk aber nein, damit befleckt man wohl die “Reinheit” von Smalltalk …

Und ja mich ärgert es auch speziell bei VBA, weil es da schon so

lange gibt und VB ein Meilenstein für die Entwicklung von Windows Programmen war. Was macht MS damit … Es ärgert mich noch mehr, wenn ich daran denke, worauf der Erfolg von MS basiert. Es war nicht zuletzt das Basic von denen, was MS an die Spitze brachte und dann macht man so was platt?

Bei Emacs ärgert mich etwas, daß es Emacs Lisp gibt. Warum konnte es kein Common Lisp sein? Stallmann kannte es doch …

Und nein, ein Guile-Emacs gibt es immer noch nicht ernsthaft …

Ja, ich weiß mach’s doch selber … Tja Punkt ist, brauche das nicht für C#, Java, C, C++, Delphi, FreePascal, TurboPascal, VB, Dolphin Smalltalk machen und ‘ne Zillion von Libraries gibt es auch ….

Ich schweig mal höflich über den Stand von IDE für die ach-so-tollen-funktionalen-Programmiersprachen … Ausnahme vielleicht F# auf Windows, aber genau weiß ich das nicht, denn Ocaml fällt bei mir unter den gleichen “Horror” wie C++ und Perl …

Ich bin der Meinung gute Werkzeuge sollte es auch für Programmierer geben und nein, die Anbieter von funktionalen Sprachen wie Haskell, leisten das nicht. Ernsthaft, wenn es um DBs geht und man, was für Anwender schaffen will, dann ist man mit MS Access besser bedient als mit jeder funktionalen PS.

Man verstehe vollkommen den Erfolg von Java, C# und so um Vergleich, weil diese Sachen einfach nützlicher sind. Und ja es dürfte mindestens ne Million mehr Anwender und Programmierer für MS Access geben als für alle funktionale PS zusammen …

Manch werden mich auslachen, es liegt doch nur an Dir, was Du nützlich findest. Ist das wirklich so? Bin ich da so eine Ausnahme? Die Prediger für die Nützlichkeit von anderen Programmiersprachen sitzen m.E. teilweise auf einem zu hohen Ross’ , keine Ahnung, ob es an mir alleine liegt, ich glaube nicht. Wenn ich an die Haskell-Evangelisten denke, dann sehe ich meine Meinung bestätigt, die Common Lisper sind leider auch nicht so viel besser … Wer die “Genialität” der Tools von denen nicht erkennt, ist wohl einfach nur ein dummy …

That really was helpful.

I struggled with some “profane” text edit duties, but well, in
over 100 files, and as a programmer … you know what we do.
Spend 3 hours to save repeating a task a few hundred times 😉

My problem, I had to match [[SomeContent]]
And I had an assoc list

setq 'assoc-listt'(("Key-1", "Value1"
                    ("SomeContent", "Some Link to")

I did not get the regular expression right, ChatGPT did it:

(defun my-function ()
  (interactive)
  (with-temp-buffer
    (insert-file-contents "filename.txt")
    (goto-char (point-min))

    ;; Search and replace
    (while (re-search-forward "\\[\\[\\(.*?\\)\\]\\]" nil t)
      (let* ((match (match-string 1))
             (value (cdr (assoc match some-alist))))
        (when value
          (replace-match (format "[[file://%s][%s]]" value match) nil t nil 1))))))

Just one problem the last 1 , that lead to the non replacement of [[ and]] replace it with zero and you’re fine. With some stuff around, with some saving of buffers, did I get what I wanted.
It’s always nice if you can program your editor, and I doubt there is anything as programmable as an Emacs 😉

Thanks for the fish – ah sorry code …

Quite interesting

That so many seem to dislike C. Yes it has its shortcomings, but it’s one of the simpler languages overall, and it deserves the name “portable Assembler”. C runs everywhere, and C has built everything we are using today. Every wider used Operating System was mostly written in C. It starts with every Unix under the sun. It’s the foundation of Windows. There may be OSes out there not written in C, but I probably know just one Genera. C allows you to manipulate bits, and that’s as low as it can get.

Nearly any Database is written in C, be it the old ones, be it the new ones. There’s some kind of C compiler on every OS. It’s the lingua franca of the IT-Industry as we know it.

Let’s wait and see if if finds a descendant, there are candidates for that, one can doubt it will bet C++.

Whatever language you use, I strongly suggest you learn C too. I doubt you will never get in touch with it, and be it just to wrap some C-API for your programming language you’re currently using.

Just for the curious

and those which don’t think MS is just the evil empire per se:
https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/

Just imagine how hard they work to get better. Yeah, they sometimes fail, but overall, they have made the PC a think everyone wants. I remind you of my critique about the dead of Visual Basic. Just imagine they have spent just a hundredth of the time they put into .NET.

It just reminds me of one thing, I think, which covers it all, see:
https://www.youtube.com/watch?v=Vhh_GeBPOhs.

VB has done more for developing more software as many other tools combined (exception might be TurboPascal) . And it’s terrible lacking in/with languages like Smalltalk, Common Lisp etc. I will never understand why one kills such a cash cow.

But they did a remarkable job with .NET, and they really spent literally Millions or even Billions on it. Anyway, I don’t know about the prices for the development environment alone because I’m buying them all at around 1500 – 1700 € / year. And so, I can use whatever I want. I know at least that VB was not in that price class, I, personally, think that dropping that was an error. Of course, I might be wrong

That’s a decent suggestion


PROCEDURE assertNoDuplicatesInTableRow(tblControl is Control,  cbColName is Control, vOldValue is Variant, sDialogText is string )

nFoundIndex					is int
nRetValDialog, nRetValInput	are int
vSearchValue, vNewValue		is string
vSearchValue	= cbColName

nFoundIndex		= TableSearch(cbColName, vSearchValue)

WHILE ((nFoundIndex > 0) AND  (nFoundIndex <> tblControl))
	nRetValDialog =  Dialog(sDialogText, ["Change", "Cancel"], 1, 2)
	IF (nRetValDialog = 1) THEN
		nRetValInput = Input("New value", vNewValue)
		IF nRetValInput = 2 THEN
			MySelf = vOldValue
			BREAK
		ELSE
			nFoundIndex = TableSearch(cbColName, vNewValue)
			IF nFoundIndex = tblControl THEN
				MySelf = vNewValue				
				BREAK
			END
		END
	ELSE
		MySelf = vOldValue
		BREAK
	END		
END



Asked ChatGPT to refactor ist:
Answer: Get rid of the loop and recall recursivly.

IF nFoundIndex > 0 AND nFoundIndex <> tblControl THEN Dialog(“Duplicate value found. Please enter a different value.”, [“OK”], 1, 1) assertNoDuplicatesInTableRow(tblControl, cbColName, vOldValue, sDialogText) ELSE MySelf = vNewValue END

That of course not WLanguage bu thte idea is decent:
One can write it this way:


PROCEDURE assertNoDuplicatesInTableRow(tblControl is Control,  cbColName is Control, vOldValue is Variant, sDialogText is string )

nFoundIndex					is int
nRetValDialog, nRetValInput	are int
vSearchValue, vNewValue		is Variant
vSearchValue	= cbColName

nFoundIndex		= TableSearch(cbColName, cbColName)

IF ((nFoundIndex > 0) AND  (nFoundIndex <> tblControl)) THEN
	nRetValDialog = Dialog(sDialogText, ["Change", "Cancel"], 1, 2)
	IF nRetValDialog = 2 THEN
			MySelf = vOldValue
	ELSE
		nRetValInput = Input("New value", vNewValue)
		IF nRetValInput = 2 THEN
			MySelf = vOldValue
			// BREAK
		ELSE
			cbColName.Value = vNewValue
			assertNoDuplicatesInTableRow(tblControl,cbColName, vOldValue, sDialogText)			
		END
	END
		
END

//WHILE ((nFoundIndex > 0) and  (nFoundIndex <> tblControl))
//	nRetValDialog =  Dialog(sDialogText, ["Change", "Cancel"], 1, 2)
//	IF (nRetValDialog = 1) THEN
//		nRetValInput = Input("New value", vNewValue)
//		IF nRetValInput = 2 THEN
//			MySelf = vOldValue
//			BREAK
//		ELSE
//			nFoundIndex = TableSearch(cbColName, vNewValue)
//			IF nFoundIndex = tblControl THEN
//				MySelf = vNewValue				
//				break
//			END
//		END
//	ELSE
//		MySelf = vOldValue
//		BREAK
//	END		
//END
//
//

Is it better? Well, it avoid a loop with different places where one has to break it
It avoids a double call to TableSearch, but replaces it with a recursive call

Other really good suggestions:

function to avoid a double in a two dimensional array

You can use a loop to iterate over the elements in the two-dimensional array and check if a given value already exists. Here’s an example implementation in C#:

csharpCopy codepublic bool CheckIfValueExistsInArray(int[,] array, int value)
{
    for (int i = 0; i < array.GetLength(0); i++)
    {
        for (int j = 0; j < array.GetLength(1); j++)
        {
            if (array[i, j] == value)
            {
                return true;
            }
        }
    }
    return false;
}

In this example, the CheckIfValueExistsInArray method takes in a two-dimensional integer array and a value to check for. It then iterates over each element in the array using two nested loops, comparing each element to the given value. If a match is found, the method returns true. If the loop completes without finding a match, the method returns false.

You can call this method to check if a value already exists in a two-dimensional array before inserting a new value. You can then decide whether or not to insert the new value based on the return value of the method.

And:

How can I avoid the double loop in the suggested code?

If you want to avoid using nested loops, you can use the Array.IndexOf method to search for the value in a flattened version of the two-dimensional array. Here’s an example implementation:

csharpCopy codepublic bool CheckIfValueExistsInArray(int[,] array, int value)
{
    int[] flattenedArray = new int[array.GetLength(0) * array.GetLength(1)];
    Buffer.BlockCopy(array, 0, flattenedArray, 0, flattenedArray.Length * sizeof(int));
    return Array.IndexOf(flattenedArray, value) != -1;
}

In this example, the CheckIfValueExistsInArray method takes in a two-dimensional integer array and a value to check for. It creates a new one-dimensional integer array with the same number of elements as the two-dimensional array by using Buffer.BlockCopy to copy the elements from the two-dimensional array to the new array. It then uses the Array.IndexOf method to search for the value in the flattened array. If the value is found, the method returns true. If the value is not found, the method returns false.

Note that this approach has some overhead because of the need to create a new flattened array, so it may not be faster than using nested loops for very small arrays. However, it can be more concise and easier to read for larger arrays.

Warum?

Was genau kann jemanden dazu bewegen, die Groß/Kleinschreibung von
Prozeduren/Methoden vorzugeben, was ist daran gut jedes Verb in Großbuchstaben zu schreiben? Und dann noch in Englisch.

Hier normaler englischer Text:

A grasshopper spent the summer hopping about in the sun and singing to his heart’s content. One day, an ant went hurrying by, looking very hot and weary.

“Why are you working on such a lovely day?” said the grasshopper.

“I’m collecting food for the winter,” said the ant, “and I suggest you do the same.” And off she went, helping the other ants to carry food to their store. The grasshopper carried on hopping and singing. When winter came the ground was covered with snow. The grasshopper had no food and was hungry. So he went to the ants and asked for food.

“What did you do all summer when we were working to collect our food?” said one of the ants.”

Wieso verlangt man in C#, daß Methoden groß geschrieben werden sollen:
Console.WriteLn(” ..

Was für eine Aussehen, da bekommt man doch das Grausen und bei Go ist es “obligatorisch”
In Go, a name is exported if it begins with a capital letter. For example, Pizza is an exported name, as is Pi, which is exported from the math package.’

WT …?

Es gibt sicherlich gute und schlechte Ideen und das ist in meinen Augen schlecht.

Bin mir darüber im Klaren

Man sollte nicht darüber lachen oder sich beschweren. X11 datiert zurück nach 1984 und es ist ein Protokoll auch für die Darstellung GUI über Leitungen von 300 Bit/s . Die Bedingungen, unter denen das laufen musste, kann man heute nicht mehr verstehen oder nur Leute, die kleinste Computer programmieren. Es macht einen Unterschied, ob man da 10 Byte oder 3 Bit übertragen muß.

Die Beschränkungen waren brutalst und jedes bisschen Leistung muß man herausquetschen. Aber natürlich von heute ausgehen, sind des APIS zum Davonlaufen, aber das teilt X11 durchaus mit der Win-API. Es waren andere Zeiten und es tut und durchaus gut, uns auch mit so was zu beschäftigen …

Was ich nicht verstehe

wie Microsoft ein so populäres Programm wie Visual Basic kaputt machte. Wenn man auch bedenkt, der Erfolg von MS war auch in einem Basic begründet. Es ist nun mehr als 20 Jahre, her und trotzdem gibt es immer noch Leute, die es benutzen.

Wieso man das nicht adaptiert und auf .NET brachte, ich habe wirklich keine Ahnung … Warum killt man eine Cash Cow? Ich meine, von unseren Politikern kann man nichts Besseres erwarten, aber von einer Firma, die sich derartige Mühe gibt, auch noch alle Software zum Laufen zu bringen.

Siehe: https://devblogs.microsoft.com/oldnewthing/

Und sie machen es wieder:
https://www.heise.de/developer/meldung/Gute-und-schlechte-Nachrichten-fuer-Visual-Basic-NET-Entwickler-4682163.html

Ich möchte gerne ein paar Stäbe brechen

Für in meinen Augen wunderbare Programmiersprachen, die leider kaum bekannt und benutzt werden. Libraries machen den Nutzen von allen Sprachen aus. Egal, wie schön eine Sprache ist, ohne Libraries ist sie leider nutzlos. Hier also ein paar Vorschläge
1) Common Lisp. Eine der derzeit am stärksten unterschätzten Sprache in den 80-er Jahren des letzten Jahrtausends gab es ganze Betriebssysteme, die in eine Lisp Dialekt geschrieben wurde. Das Emacs Lisp begleitet uns nun seit mehr als 30 Jahren, ein Ende ist nicht absehbar. Schemes gibt es sehr viele und auch noch ein paar andere weniger bekannte Lisps. Wenn Sie Glück und Können haben, bekommen die dieses BS auf Linux zum Laufen

https://archives.loomcom.com/genera/genera-install.html

Downloads / Homepages: https://www.sbcl.org/ http://www.lispworks.com, http://www.franz.com, https://franz.com/
2) Smalltalk. Eine der ersten Durch- und Durch Sprachen auf der Basis von Objekten. Heute immer noch unerreicht. Leider fast vollkommen vergessen im Lichte von Nachfolgern wie Python, C#, Java, JavaScript, C++. Smalltalk teilt mit Common Lisp die Eigenschaft, eine programmierbare Programmiersprache zu sein. Es gibt wenige andere Sprachen, mit denen man die Sprache selber so erweitern kann. So kann man z.B. neue Schleifenarten ohne Probleme zu diesen Sprachen hinzufügen.

Downloads: https://pharo.org/, https://squeak.org/, https://www.instantiations.com/,
https://www.gnu.org/software/smalltalk/

Die “Schwäche” der beiden Sprachen aus Sicht von vielen sind fehlende statische Typen. Interessanterweise teilen sie das mit Python, was derzeit aber eine der am meistgebrauchten Programmiersprachen ist

3) Io . Ich bezweifele, daß es mehr als 1000 aktive Benutzer gibt. Die Einfachheit dieser Sprache ist besser als bei Smalltalk. Hier können Sie es sich anschauen: https://iolanguage.org/
Mehr gibt es nicht. Hier eine Idee wie es aussehen kann:

 cc := method(System getEnvironmentVariable("CC") ifNilEval(return "cc"))
    cxx := method(System getEnvironmentVariable("CXX") ifNilEval(return "g++"))
    ccOutFlag := "-o "
    linkdll := cc
    linkDirPathFlag := "-L"
    linkLibFlag := "-l"
    linkLibSuffix := ""
    linkOutFlag := "-o "
    linkLibSuffix := ""
    ar := method(System getEnvironmentVariable("AR") ifNilEval(return "ar"))
    arFlags := "rcu "
    ranlib := method(System getEnvironmentVariable("RANLIB") ifNilEval(return "ranlib"))


includes = includes appendSeq(headerSearchPaths) map(v, "-I" .. v)

 iocFiles := sourceFiles select(f, f name beginsWithSeq("Io") and(f name endsWithSeq(".c")) and(f name containsSeq("Init") not) and(f name containsSeq("_") not))

Es ist sehr im Smalltalk Sinn gehalten. Object message ist der Weg. Es gibt keine speziellen Klassen. Alles kann eine Klasse sein, aber alles ist ein Objekt. M.E. ist die Implementierung eine der besten (im Sinne von lesbarsten) , die ich bisher fand.

Vielleicht stelle ich auch noch ein paar andere Sprachen vor, die mich auf die eine oder andere Weise beeindruckten….

Genugtuung

Für einige Programmierer. Es gibt eine völlig unterschätzte Sprache, Lisp in diversen Varianten. Ein Beispiel was ein Lisp kann, aber nicht viele andere Sprachen:

(defmacro define-advice (symbol args &rest body)
  "Define an advice and add it to function named SYMBOL.
See `advice-add' and `add-function' for explanation on the
arguments.  Note if NAME is nil the advice is anonymous;
otherwise it is named `SYMBOL@NAME'.

\(fn SYMBOL (WHERE LAMBDA-LIST &optional NAME DEPTH) &rest BODY)"
  (declare (indent 2) (doc-string 3) (debug (sexp sexp body)))
  (or (listp args) (signal 'wrong-type-argument (list 'listp args)))
  (or (<= 2 (length args) 4)
      (signal 'wrong-number-of-arguments (list 2 4 (length args))))
  (let* ((where         (nth 0 args))
         (lambda-list   (nth 1 args))
         (name          (nth 2 args))
         (depth         (nth 3 args))
         (props         (and depth `((depth . ,depth))))
         (advice (cond ((null name) `(lambda ,lambda-list ,@body))
                       ((or (stringp name) (symbolp name))
                        (intern (format "%s@%s" symbol name)))
                       (t (error "Unrecognized name spec `%S'" name)))))
    `(prog1 ,@(and (symbolp advice) `((defun ,advice ,lambda-list ,@body)))
       (advice-add ',symbol ,where #',advice ,@(and props `(',props))))))

Man muß dazu schon, was mir AOP anfangen können, um da mitzuziehen. Und das ist Standard in so gut wie jedem Lisp. Im Beispiel ist es Emacs-Lisp eine Programmiersprache so alt wie der Emacs selber, also seit 1984 (und das sind nun 2023 – 1984 = 39 Jahre). Und Lisp ist noch älter, es war immer schon eine programmierbare Programmiersprache. Neue spezielle Schleifen – check. Einseitige Fallunterscheidungen wie when und unless – check.

Viele lachen über Lisp, aber nur noch wenige wissen, was Lisp Machines waren und was die boten.

Lispprogrammierer kann man mit Liberalen in der Politik vergleichen 😉

An die Programmierer

zu denen auch ich gehöre. Ich finde, für uns sind die Zeiten besser als je. So viele Sprachen, aus denen man auswählen kann, teilweise mit einer traumhaften Infrastruktur. Als ich anfing, gab es
kein Java, kein C#, kein F#, kein JavaScript, kein PHP, kein Python, kein Ruby, kein Rust, kein Go und was weiß ich, was alles noch dazu gekommen ist.

Bei uns gab es C, Modula-2, Pascal, Basic, Fortran, Cobol und Ähnliches. Die IDEs damals waren definitiv nicht so ausgefuchst wie heute. Wir hatten die Wahl, aber die war weitaus beschränkter als derzeit. Es ist auch so viel an neuer Software dazu gekommen, es ist geradezu atemberauben.

Wäre die politische Entwicklung nur halb so schön gewesen, bräuchte ich mir keinerlei Gedanken über das Auswandern machen …

Ich schlage vor, wir genießen die Auswahl und programmieren, worin auch immer wir Spaß haben…

I agree

It’s stupid not to use some software, because in what it is written. Of course I have my favourites, and special dislikes. But that is not what I see as a user. If the software does what it should – it’s fine.

What try to avoid is of course using a programming language for programming if I do not like it.
And I have a special distaste of C++ and Perl. Partly Tcl ( I simply do not like the set x val) Of course it is stupid. Strange enough I find C a wonderful language.
Now I’m currently learning Java and I’m quite sure I will use it for further programm development. I want to learn and use other languages but many are terrible for application development. You want a decent debugger and decent toolbos. This is not a given for quite a few languages I like.

E.g I’d like to use Pharo Smalltalk more intensivly, but they break code way too often. As a application developer I hate that, and for that I have to like VBA, because it simply works since at least two decades. Code you once wrote, still works. Every language which breaks code too often is very much a no-go for me. What I need is help with building GUI and Reports. If that’s not there I an’t use it….

Ich habe eine Schwäche für

Smalltalk der Programmiersprache. Was mich aber unglaublich ärgert, ist die Problematik von neuen Versionen zum Beispiel bei Pharo Smalltalk. Die Entwicklungsversion ist 11, daran läuft aber alles Mögliche nicht mehr sei Moose, Seaside oder. Was genau denken sich die Entwickler, wenn Sie mit neuen Versionen alte Software nicht mehr laufen lassen können.

Das ist IMHO eine ganz schlechte Idee und es ist ein Grund, warum ich immer noch C mag. So etwas passiert Ihnen in C nicht! Es passiert Ihnen auch in VBA so schnell nicht und es passiert Ihnen auch eher nicht in kommerziellen Smalltalks.

Ich verstehe, wenn man Fehler beheben will, ich verstehe, wenn man etwas anders implementiert, aber ich verstehe nicht, wie man Anwendungsentwickler so hängen lässt.

Mal “wieder” was übers Programmieren

Wahrscheinich überrascht es keinen, wenn ich schreibe, damit verbringe ich einen Teill meines Lebens. Mich haben Programmiersprachen schon immer interessiert und ich habe wirklich einiges auf mich genommen um in bestimmten davon arbeiten zu können. Zu meiner Zeit an der Uni war es die Möglichkeit eiffel zu benutzen.
https://de.wikipedia.org/wiki/Eiffel_(Programmiersprache)

Die Idee dahinter scheint mir heute noch eine der wirkich besseren zu sein. Es gibt dort ein Prinzip, nennt sich CQS (command query separation) und es meint. Das nur Methoden den Zustand eines Objektes ändern sollte, es in Abfragen aber nicht vorkommt.

Beispiel set_x(some_Value)  enthält nur x := someValue
Aber get_x():someValue enthält nur result := x

Bei dem einen ändert man den Zustand einer  Variiablen bei der anderen darf/sollte man es nicht.

C Programmierer kennen das Problem mit Rückgabewerten. Wo packt man den/die hin? In C gibt es kein “Tupel” Konzept und man kann nur einen Wert zurückgeben, dieser eine Wert kann aber auch ein void* sein und das kann wirklich alles sein. Auf der anderen Seite, wie informiert man den Benutzer, daß etwas schief gegangen ist. Das wird in sehr vielen Bibliotheken eben über den Rückgabewert erledigt. Darum findet man in C so etwas

#define ERROR_SUCCESS 0
#define ERROR_WHATEVER 1
Vielleicht in angenehmeren  Code in einem enum. Der Rückgabewert gibt also an ob alles “glatt” ging oder nicht, damit ist dannn aber der Rückgabewert “weg” und man muß sich mit globalen Variablen oder veränderbaren Parmetern behelfen.

Hier zwei Lösungen aus anderen Programmiersprachen:
https://doc.rust-lang.org/book/ch09-00-error-handling.html
https://go.dev/doc/tutorial/handle-errors

In Smalltalks gibt es nur Messages die etwas zurückgeben…

Aber nun kommen wir zu Programmiersprachen, die Seiteneffekte gar nicht leiden können und nur auf “pure” Funktionen setzen. Das bedeutet, wenn man diese aufruft ergeben die mit denselben Eingabedaten immer, diegleichen Ergebnisse. Die “dreckige” Arbeit von Seiteneffekten muß speziell gekennzeichnet werden. Prominentestes Beispiel dürfte Haskell sein (dazu eines der besten Bücher, was man auch online finden kann  http://book.realworldhaskell.org/read/)

In jedem Buch wird die “Reinheit” der Sprache gelobt, handelt es sich um eine “unreine” Methode also mit Seiteneffekten wird es immer irgendei IO type werden, das nennen die Monad.

Nun, die Autoren behaupten es sei der größte Vorteil. Ich stimme soweit durchaus mit ihnen überein, aber ich behaupte auch es ist der größte Nachteil, damit stimme ich als nicht mit Ihnen überein.

Ich bin immer mehr zur Überzeugung gekommen, daß der ausbleibende Erfolg von funktionalen Sprachen damit zusammenghängt. Es sieht so aus als ob Zustand – Zustandsänderung -> neuer Zustand für wirklich die allermeisten Programmierer einfacher verständlich ist und dem normalen Denkmodell entspricht. Was man uns nicht verdenken kann. Sitzen Sie in einem Auto und wollen los fahren, müssen Sie etwas tun. Einen Gang einlegen, Kupplung kommen lassen und entsprechend Gas geben, dann fährt ein Auto eben los, der Zustand ändert sich von stehendem Auto -> fahrendem Auto.

Ich denke auch, daß eben Zustandveränderungen genau das sind was man in allen anderen Bereichen macht. Dieses hinter einem Monad zu verstecken, scheint für mich einer der Hauptgründe zu sein, warum  man Funktionale Programmiersprachen nicht in größeren Bereichen kennt. Betrachtet man unsere gesamte Infrastruktur, dann wird man eher früher als später auf C treffen. Trotz aller Probleme damit, trotz der problematischen nebenläufigen Programmierung. So gut wie alle Betriebsysteme benutzen C als Basis und es gilt selbstredend speziell auch für jedes Unix, heiße es LInux, BSD, Solaris, HP-UX, AIX. So gut wie jeder relationale Datenbank ist in C geschrieben und manche davon werden tatsächlich milliardenfach benutzt (z.B. sqlite)

Ich persönlich kenne wirklich kein Programm, welches ich täglich benutze, daß in einer funktionalen Sprachhe implementiert wurde. Man kann behaupten, das derzeitige vorherrschende Programmiermodel basiert auf Klassen, Objekten und Messages.

Ja, es ziehen funktionale Elemente in OO-Sprachen ein, aber Blöcke sind in Smalltalk ein uraltes Konzept! Kurz die neuen PS müssen sich an einer der ältesten noch benutzen PS anlehnen. Das finde ich höchst interessant und erklärt vielleicht zu einem Teil warum ich Smalltalk für eine der besten Programmiersprachen halte.

Nur was Programmierer oder Leute mit einem Hang zur Programmmierung

Mal ‘ne wie geht es Ihnen Frage. Nur was für Programmierer oder programmmieraffine.

Geht es Ihnen auch so, daß Sie bestimmte Programmiersprachen mögen und andere einfach nicht?

Ich merke es immer und immer wieder. Sprachen die ich mag:
Smalltalk, C, Ruby, Eiffel, Scheme, Common Lisp, IO, Self, D, Dylan, SQL (auch procedural SQL)

eher indifferent:
C#, Java, Python, Tcl/Tk

mal so / mal anders
Haskell, Ocaml, F#, WLanguage, VBA

mag ich nicht / gruselig
C++, Perl, Brainfuck ;-),

Es ist natürlich irgend irrational. Nur wenn ich die Wahl habe, nehme ich lieber die ich mag.

Was ich aber ganz klar mag. Interaktive Entwickliungsumgebungen, wo man einfach mal was ausprobieren kann, ich schätze auch gute Debugger und dann die Möglichkeit Teile es Code genauer zu untersuchen (wahrscheinlich ein Grund warum ich Smalltalk so gut finde)

Und ja es ist klar eine Präferenz für OO vorhanden. Offenbar kommt es meiner Gedankenwelt am Nächsten. Wie geht es Ihnen?

Microsoft und der Umgang mit Progammierern

Erstaunt mich:
https://www.heise.de/developer/meldung/Gute-und-schlechte-Nachrichten-fuer-Visual-Basic-NET-Entwickler-4682163.html

Wenn man bedenkt was Visual Basic alleine schon für die Popularität der Entwickliung auf Windows brachte. Dann tritt man diesen Leuten mit Visual Basic Net auf die Zehen und keine 20 Jahre später, tritt man den Basic Fans noch mal mit Schmackes in’s Gemächt.

Bin mal gespannt was aus dem dann hier wird:
https://www.twinbasic.com/

Wenn man bedenkt, ehemals war das Mantra: Entwickler, Entwickler und nocht mehr Entwickler. Die man sicher mit VB bekam und dann so etwas …

Marktführerschaft kann nett sein, aber für die sich darauf eingeschossen haben …

An die Programmierer unter meinen Lesern,

so es Sie denn geben sollte.

An die Programmierer oder an Programmierung interessierten unter meinen Lesern. Kleiner Hintergrund: Ich kenne inzwischen eine ganze Menge Programmiersprachen, manche davon benutze ich intensiv, manche habe ich intensiv benutzt und bei anderen habe ich es immer mal wieder versucht, manche kann ich ganz gut lesen und schreiben, manche verstehe ich so gerade, manche mag ich und ein paar Kandidaten eher nicht.

Nun bin ich nach längerer Zeit auch mal wieder auf den Gebrauch von Common LIsp, gekommen, ich hab auch meine Emacs ordentlich gepimpt und was soll ich sagen – es rockt

Meine Firma hat mal eine Zeitlang LIspWorks vertrieben: http://www.lispworks.com/ Gestern habe ich mir auch mal AllegroCL auf meinem Rechner installiert.

Da ich einige Jahre CL gar nicht benutzt habe, muß ich festhalten: Es hat sich einiges zum besseren gewendet (was mich freut)

Wie auch immer, gestern stolper ich über eine Anwendung, die ich vor ungefähr 15 Jahren geschrieben habe und ich dachte mir, schau mal was da noch geht und zu meinem größten Erstaunen, brauchte ich nur das Tools installieren (in diesem Falle Lispworks Personal Edition) und bekam ein CAPI – Programm (das ist das GUI von Lispworks ) auf Linux und Windows zum Lauren. Das war erfreulich und interessant.

Nun habe ich auch bei diversen “Challenges” mitgemacht und treibe mich auch in wirklich “obskuren” Ecken herum (wem sagt CLIM etwas?)

Was ich aber immer mal wollte war ein Buch mit vielen Implementierungen in diversen Programmiersprachen. Es gibt ein Buch wo das mal ansatzweise versucht wurde “Beautiful code” aber dort gibt es eben nicht ein Beispiel und nun möchte ich Sie und mich herausfordern, ich gedenke eine Seite in’s Netz zu stellen wo genau eine Anwendung implementiert wird mit “Challanges” dann daran Änderungen zu übernehmen.

Im Augenblick denke ich an 3 Schnittstellen
1) CLI
2) GUI
3) Web

An diverse Arten von Speicherung der Daten
1) plain files
1.1) in welchem Format auch immer
1.2 ) in sagen wir mal CSV, JSON etc
2) Databases
3) was auch immer (Smalltalks images….)

Die Daten sollen verschlüsselt werden und es sollte möglich sein daraus die Daten an den WebBrowser zu übermittteln.

Was dann aber auch kommt. Interfacing mit anderen Sprachen egal wohin, aber es soll z.B. möglich sein, die sagen wir mal CL Strukturen aus einer andereen Sprache zu benutzen, Wie einfach schwierig ist es.

Bewertet wird die Software von den Besuchern der Seite wo ich das alles Sammeln möchte.Unter anderem
– Fehleranfälligkeit
– Lesbarkeit
– Adaptionsfähigkeit
– Tests
– Installation
– Implementierungszeit
– Wartbarkeit
– Sicherheit

Das ganze soll länger laufen, es kommt eben auf die Herauforderungen und deren Umsetzung an. Vielleicht kennt jemand die Language Shootout Seiten, dort ging es aber nur im Speed, Das will ich gar nicht “klein” reden, nur darum geht es mir nicht. Ich möchte einfach eine Anwendung auf möglichst viele Weisen implementiert sehen, um einfach mal zu zeigen, wie interessant das sein kann

Den Zeitaufwand kann ich nicht “beziffern”, damals habe ich vielleicht einen Tag oder so gebraucht – keine Ahnung. Kannte das ja einfach nicht

Mich faszinieren Programmiersprachen und ich bin speziell dafür sich auch die Nicht-Mainstream Sprachen anzuschauen. Ich kann mir nicht vorstellen, daß ich damit alleine bin. Wäre da jemand evtl interessiert?

Anwendung: Speicherung von Zugangsdaten mit “natürlich” Verschlüsselung, export/import dieser Daten in diversen Formaten,

Für Interessierte

Ich verfolge die “offiziellen” Zahlen von hier: https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6

In der angefügten Tabelle habe ich darau seien Exponentieleln Angleichung berechnern lassen die leider sehr genau stimmt.

Für die Quualität der Zahlen kann ich keinerlei Gewähr übernehmen, nur schreiben, die Formeln ergeben sich aus den geposteten Zahlen. Was extrem auffällt, ist die Abweichung der CRF und der CRF(t), danach sind wir in D ein Land der am wenigsten von Tod betroffenen durch Corona.

Achtung bei den Toten ist festzuhalten. Wer es hat und stirbt wird als Corona Toter gewertet – auch in D!

Corvid-Tabelle-2020

Nun mal zu was ganz Neuem

Jedenfalls für mich den Autor. Ein “bisschen” Geschichte um es einordnen zu können.  Ich bin einer der frühen Nutzer von Linux. Angefangen habe ich mit irgendwas unter 1. Das dürfte nun mehr als sogar 30 Jahre her sein. Mitgemacht habe ich seit der Installatoin mit den kleinen Floppies. Keine Ahnung ob noch jemand weiß, was das war. Angefangen habe ich mit irgendwas von Suse oder so – IIRC. Nun nach einiger Zeit landete ich bei Debian (genau so um 1998) herum. Seitdem bin ich intensiver Debian und neuerdings auch Ubuntu  Benutzer. Das Ubunti kam auf dem aktuellen Rechner drauf den ich gerade benutze weil irgendwas in Debian mit dem X-Window nicht klappte. Also mal ‘ne Ubuntu probiert.

Ich kann hauptsächlich gutes zu Debian sagen. Ein wirklich solides System mit einem ganz erstaunlichen Paket-system. Es gibt wirklich selten Probleme selbst mit einem Systemupgrade. Was ich speziell benutze ist VirtualBox, das ist wirklich auch beruflich wichtig für mich, da die Software meiner Firma auf Windows  läuft. Ich war eine lange Zeit Benutzer von vmware und habe dafür auch gut bezahlt. Weiterhin habe ich einige Software auch auf Linux gekauft. Ich administriere selber noch einige Linux Rechner für Familie, Kunden und auch die PDV. Ich denke wer so lange Linux benutzt und auch von Floppies noch installiert, der findet sich passabel bis gut zurecht.

Allerdings habe ich schon immer meine persönlichen Problem mit der GPL, https://www.gnu.org/licenses/gpl-3.0.html. Diese behauptet zwar für “Freiheit” zu sein. Fakt ist aber man wird durch Sie und deren Gebrauch sehr eng gebunden. Ja Sie können, die Quellen einsehen und ja Sie können die auch beliebig verändern und nein das können Sie im Grunde nicht für sich behalten. Freiheit ist nicht nur die Freiheit etwas nutzen zu dürfen sondern auch mit dem genutzten zu machen was man will. Die GPL schränkt das ein. Für mich ist das nicht zum Guten.

Es ist aber auch so, daß fast jeder irgendwo mit einem Linux Kontakt hat und ich denke wenn ich schreibe 80 % des Internet basieren auf Linux ist das nicht übertrieben. Linux ist wirklich überall und inzwischen sehr sehr gut geworden. Ohne Zweifel und ich gratuliere den Leuten die das auf die Beine gestellt haben uneingeschränkt.

Debian ist sehr konsequent was Fremdsoftware und “proprietäre” Sachen angeht. Das kann man schätzen, muß man aber nicht. Ich schätze es nicht so sehr. Daher wolle ich immer schon was freieres ausprobieren und das habe ich zwischen drin mal versucht. Die noch freieren System sind BSD System davon gibt es sicher  mehr als 3 aber die bekanntesten sind:

FreeBSD: https://www.freebsd.org/de/
OpenBSD: https://www.openbsd.org/
NetBSD: https://www.netbsd.org/

Man kann wohl schreiben FreeBSD ist da mit den meisten Installationen. OpenBSD nimmt für sich in Anspruch eines der sichersten Linux Systeme überhaupt zu sein, NetBSD behaupte, egal was es an Hardware gibt es NetBSD wird schon drauf laufen.
Man siehe auch: https://www.unixmen.com/freebsd-vs-openbsd/

Die Lizenz von FreeBSD kann man hier anschauen: https://www.freebsd.org/copyright/freebsd-license.html

Das ist definitiv freier, der COC (code of conduct) hingegen ist wohl feministischer Dreck (irgendwas ist ja immer) . Ich denke das mit dem Dreck könnte hinkommen:

Some FreeBSD Project spaces may have additional rules in place, which will be made clearly available to participants. Participants are responsible for knowing and abiding by these rules. Harassment includes but is not limited to:

  • Comments that reinforce systemic oppression related to gender, gender identity and expression, sexual orientation, disability, mental illness, neurodiversity, physical appearance, body size, age, race, or religion.
  • Unwelcome comments regarding a person’s lifestyle choices and practices, including those related to food, health, parenting, drugs, and employment.
  • Deliberate misgendering.
  • Deliberate use of “dead” or rejected names.
  • Gratuitous or off-topic sexual images or behaviour in spaces where they’re not appropriate.
  • Physical contact and simulated physical contact (e.g., textual descriptions like “*hug*” or “*backrub*”) without consent or after a request to stop.
  • Threats of violence.
  • Incitement of violence towards any individual, including encouraging a person to commit suicide or to engage in self-harm.
  • Deliberate intimidation.
  • Stalking or following.
  • Harassing photography or recording, including logging online activity for harassment purposes.
  • Sustained disruption of discussion.
  • Unwelcome sexual attention.
  • Pattern of inappropriate social contact, such as requesting/assuming inappropriate levels of intimacy with others.
  • Continued one-on-one communication after requests to cease.
  • Deliberate “outing” of any private aspect of a person’s identity without their consent except as necessary to protect vulnerable people from intentional abuse.
  • Publication of non-harassing private communication without consent.
  • Publication of non-harassing private communication with consent but in a way that intentionally misrepresents the communication (e.g., removes context that changes the meaning).
  • Knowingly making harmful false claims about a person.”

Das hat m.E. bei Software nichts verloren.

Dieses FreeBSD habe ich auf einem Notebook installieren können und werde und will mal sehen wie ich damit hinkomme.

Wenn Sie mal einen Blick in Debian und FreeBSD werfen wollen, dann schauen Sie in die Handbücher:
Debian: https://www.debiananwenderhandbuch.de/
FreeBSD: https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/

Ich persönlich halte einige in Debian für falsch: So die Umstellung auf systemd. Ich bin der Meinung gerade bei Unices sollte KISS immer gelten und eingehalten werden. Einfach halten und das “einfachste” was ich kenne und was sicher noch auch in 100 Jahren funktionieren wird, sind Textdateien. Wir werden zig-hundertausende Dateiformate nicht mehr lesen können aber eine Textdatei wird auch in 100 Jahren noch funktionieren.

Mein neues Abenteuer heißt also: FreeBSD verstehen und nutzen lernen. Mal schauen wo das hinführt.

Gleich mal in 2 Probleme: 1) Ich weiß noch nicht wie ich von da werde drucken können
2) die Firewall regeln laufen gleich mal wieder anders und müssen anders konfiguriert werden.

 

My take on it

https://martinfowler.com/articles/is-quality-worth-cost.html

I maintain some software for around 8 years now. And I just can tell from that: Organize your code and rewrite if it has some quality. The software I have, works but is terrible hard to extend and the really realyl big problem. I do have to add this extensions over and over again. At least if it’a about order, I’ have 4 different areas which nearly are the same to change. That makes it terrible and you can bet, I’ll oversee one area nerly always.

Be very carefula bout redundancy, but don’t get folled and think it’s always bad, but if it’s in more then three places, you are in deep trouble.

Yes quality matters and it’s worth it. It’s worth your time and it will hamper the further development if you don not care about it deeply.