DedSec Project

scheme — συγκεντρωτικός οδηγός — DedSec Project

scheme — συγκεντρωτικός οδηγός Scheme Μοντέλο λειτουργίας Η Scheme είναι Lisp γλώσσα με lexical scope, συναρτήσεις και μικρό πυρήνα, με διαφορές μεταξύ standards. Παράδειγμα Δοκίμασέ το με…

Scheme

Μοντέλο λειτουργίας

Η Scheme είναι Lisp γλώσσα με lexical scope, συναρτήσεις και μικρό πυρήνα, με διαφορές μεταξύ standards.

Παράδειγμα

(define (sum xs)
  (if (null? xs) 0 (+ (car xs) (sum (cdr xs)))))

Δοκίμασέ το με νόημα

Παρακολούθησε αναδρομικό άθροισμα και απόδειξε ότι η κενή λίστα τερματίζει· δοκίμασε μία τιμή.

Σφάλμα που πρέπει να ξεχωρίσεις

Η σύνταξη και οι βιβλιοθήκες διαφέρουν σε R5RS/R7RS και implementations.

Για να κρίνεις την άσκηση, κατέγραψε την αρχική είσοδο, την πρόβλεψη και την παρατήρηση σε πραγματικό, συμβατό περιβάλλον Scheme. Δώσε ξεχωριστό παράδειγμα όπου αλλάζει μόνο μία μεταβλητή ή ένα όρισμα. Αν εργάζεσαι χωρίς την αναγκαία εφαρμογή, μελέτησε τη σύνταξη ως παράδειγμα και μην παρουσιάζεις το κείμενο ως εκτελεσμένο test.

Scheme — Αναλυτικός οδηγός εξάσκησης

Παράδειγμα με βασικές μορφές R5RS

Οι υλοποιήσεις Scheme έχουν διαφορετικές επεκτάσεις. Μείνε αρχικά σε βασική σύνταξη:

(define (first-result xs)
  (if (null? xs)
      (list 'empty)
      (list 'value (car xs))))
(display (first-result '(7 8)))
(newline)
(display (first-result '()))
(newline)

Αναμένονται (value 7) και (empty). Το tag έχει σημασία: αν επέστρεφες μόνο #f για κενή είσοδο, θα το μπέρδευες με λίστα που περιέχει νόμιμη τιμή #f. Σύγκρινε με (first-result '(#f 2)). Χρησιμοποίησε συμβατό mode R5RS και κατέγραψε υλοποίηση/έκδοση, επειδή διαφέρουν οι παρεχόμενες επεκτάσεις.

Έλεγξε πριν από το car

Η κλήση car με άδεια λίστα παραβιάζει το συμβόλαιο εισόδου της. Η null? πρέπει να προηγείται. Δημιούργησε ξεχωριστά σκόπιμα λανθασμένη συνάρτηση χωρίς έλεγχο και κράτησε το πραγματικό diagnostic. Δεν παρέχουν όλα τα Scheme dialects τις ίδιες βιβλιοθήκες ή μηχανισμούς εξαιρέσεων· μην παρουσιάζεις κάποια επέκταση ως καθολικό κανόνα.

Δομή αναδρομής

Όρισε άθροισμα λίστας με βάση την (null? xs) και υπολογισμό (+ (car xs) (sum-list (cdr xs))). Δείξε γιατί η cdr μειώνει την πεπερασμένη σωστή λίστα μέχρι τη βασική περίπτωση. Δοκίμασε κενή λίστα και αρνητικούς αριθμούς. Ένα dotted pair δεν είναι κανονική λίστα και μπορεί να αποτύχει όταν η αναδρομή περιμένει κενή κατάληξη.

Πρόσθετη δοκιμή

Σύγκρινε eq? με equal? σε ζεύγη και αριθμούς. Διευκρίνισε αν χρειάζεσαι δομική ισότητα ή ταυτότητα αντικειμένων. Μη βασίζεσαι στην τυχαία ταυτότητα για σύγκριση περιεχομένου. Σημείωσε αν ο διερμηνευτής ακολουθεί R5RS ή πιο σύγχρονο dialect. Πρότυπο: https://standards.scheme.org/

Scheme — Διαδρομή ουσιαστικής εξάσκησης

Αναδρομικό άθροισμα

Μια συνάρτηση Scheme επεξεργάζεται τις λίστες αναδρομικά. Στην παρακάτω έκδοση ο accumulator κρατά το άθροισμα των θετικών τιμών που έχουν ήδη εξεταστεί, ενώ το remaining αντιστοιχεί στο ανεπεξέργαστο μέρος.

(define (sum-positive xs)
  (let loop ((remaining xs) (total 0))
    (cond ((null? remaining) total)
          ((> (car remaining) 0)
           (loop (cdr remaining) (+ total (car remaining))))
          (else (loop (cdr remaining) total)))))
(sum-positive '(4 -2 0 7))
(sum-positive '())

Η πρώτη κλήση αναμένεται να δώσει 11, η δεύτερη 0. Εδώ η αναδρομική κλήση βρίσκεται σε tail position, πράγμα σημαντικό για την εγγύηση proper tail recursion της γλώσσας. Σύγκρινέ τη με μια έκδοση που πρώτα καλεί recursively και μετά προσθέτει· στη δεύτερη χρειάζεται να διατηρείται εκκρεμής πρόσθεση.

Ελεγχόμενη αποτυχία

Η car σε κενή λίστα δεν επιστρέφει κενή λίστα ούτε μηδέν: είναι σφάλμα. Το null? πρέπει να προηγείται. Αν η λίστα περιλαμβάνει συμβολοσειρά, η > δεν ορίζεται για αυτή την τιμή. Δοκίμασε '(4 "bad" 7) σε ελεγχόμενο interpreter και πρόσθεσε number? αν θέλεις να επιτρέπεις ετερογενείς λίστες. Προτίμησε σαφή απόρριψη αντί για σιωπηρή μετατροπή.

Παρενέργειες και όρια

Η map παράγει νέο αποτέλεσμα από την αρχική λίστα χωρίς μεταβολή της εισόδου. Το set! αλλάζει μια δέσμευση, όχι κατ' ανάγκη το ίδιο το αντικείμενο, και συνεπώς δεν αποτελεί ισοδύναμη πράξη. Το set-car! υπάρχει μόνο σε ορισμένες διαλέκτους/τύπους ζευγών. Γράψε μια έκδοση με fold-left μόνο εφόσον το παρέχει ο interpreter που χρησιμοποιείς.

Άσκηση επαλήθευσης

Υλοποίησε την ίδια συνάρτηση για λίστα μόνο με αρνητικά, για κενή λίστα και για δέκα χιλιάδες αριθμούς. Σημείωσε ακριβή διάλεκτο, interpreter και αποτέλεσμα κάθε περίπτωσης. Παράδωσε το invariant του accumulator με δικά σου λόγια και ένα counterexample για λανθασμένο null? έλεγχο. Το παράδειγμα εδώ είναι στατικό εκπαιδευτικό υλικό· δεν ισχυρίζεται εκτέλεση στο συγκεκριμένο audit.